Skip to content

Commit ae6e09b

Browse files
committed
Add X-Content-Type-Options and Referrer-Policy security headers
Add two missing security headers to the existing securityHeadersMiddleware: - X-Content-Type-Options: nosniff — prevents browsers from MIME-sniffing responses away from the declared Content-Type, stopping e.g. a user-uploaded image from being reinterpreted as executable HTML/JS - Referrer-Policy: strict-origin-when-cross-origin — limits URL information leaked in the Referer header on cross-origin requests to just the origin (no path), and sends nothing at all on HTTPS-to-HTTP downgrades
1 parent 638fa63 commit ae6e09b

File tree

2 files changed

+14
-1
lines changed

2 files changed

+14
-1
lines changed

backend/app/rest/api/rest.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,14 @@ func cacheControl(expiration time.Duration, version string) func(http.Handler) h
618618
}
619619
}
620620

621-
// securityHeadersMiddleware sets security-related headers: Content-Security-Policy and Permissions-Policy
621+
// securityHeadersMiddleware sets security-related headers:
622+
// - Content-Security-Policy: controls which resources the browser is allowed to load
623+
// - Permissions-Policy: disables browser features (camera, mic, etc.) not needed by a comment widget
624+
// - X-Content-Type-Options: prevents browsers from MIME-sniffing responses away from the declared type,
625+
// stopping e.g. a user-uploaded image from being reinterpreted as executable HTML/JS
626+
// - Referrer-Policy: controls how much URL information leaks in the Referer header on cross-origin
627+
// requests; "strict-origin-when-cross-origin" sends only the origin (no path) to other domains
628+
// and nothing at all on HTTPS→HTTP downgrades
622629
func securityHeadersMiddleware(imageProxyEnabled bool, allowedAncestors []string) func(http.Handler) http.Handler {
623630
return func(next http.Handler) http.Handler {
624631
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@@ -632,6 +639,8 @@ func securityHeadersMiddleware(imageProxyEnabled bool, allowedAncestors []string
632639
}
633640
w.Header().Set("Content-Security-Policy", fmt.Sprintf("default-src 'none'; base-uri 'none'; form-action 'none'; connect-src 'self'; frame-src 'self' mailto:; img-src %s; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; font-src data:; object-src 'none'; frame-ancestors %s;", imgSrc, frameAncestors))
634641
w.Header().Set("Permissions-Policy", "accelerometer=(), autoplay=(), camera=(), cross-origin-isolated=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(), gamepad=(), hid=(), idle-detection=(), interest-cohort=(), serial=(), unload=(), window-management=()")
642+
w.Header().Set("X-Content-Type-Options", "nosniff")
643+
w.Header().Set("Referrer-Policy", "strict-origin-when-cross-origin")
635644
next.ServeHTTP(w, r)
636645
})
637646
}

backend/app/rest/api/rest_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,8 @@ func TestRest_securityHeaders(t *testing.T) {
352352
defer resp.Body.Close()
353353
assert.Equal(t, http.StatusOK, resp.StatusCode)
354354
assert.Contains(t, resp.Header.Get("Content-Security-Policy"), "img-src *;")
355+
assert.Equal(t, "nosniff", resp.Header.Get("X-Content-Type-Options"))
356+
assert.Equal(t, "strict-origin-when-cross-origin", resp.Header.Get("Referrer-Policy"))
355357
teardown()
356358

357359
// check CSP with proxy enabled
@@ -364,6 +366,8 @@ func TestRest_securityHeaders(t *testing.T) {
364366
defer resp.Body.Close()
365367
assert.Equal(t, http.StatusOK, resp.StatusCode)
366368
assert.Contains(t, resp.Header.Get("Content-Security-Policy"), "img-src 'self';")
369+
assert.Equal(t, "nosniff", resp.Header.Get("X-Content-Type-Options"))
370+
assert.Equal(t, "strict-origin-when-cross-origin", resp.Header.Get("Referrer-Policy"))
367371
}
368372

369373
func TestRest_subscribersOnly(t *testing.T) {

0 commit comments

Comments
 (0)