diff --git a/internal/ui/ui.go b/internal/ui/ui.go index d6d13b0..ee942f3 100644 --- a/internal/ui/ui.go +++ b/internal/ui/ui.go @@ -545,6 +545,9 @@ const maxFormBytes = 1 << 20 // requests to this origin for two years, preventing TLS-strip on revisit. // - Referrer-Policy: suppresses the Referer header on outbound navigations so // JWTs or session identifiers embedded in URLs are not leaked to third parties. +// - Permissions-Policy: disables browser features (camera, microphone, +// geolocation, payment) that this application does not use, reducing the +// attack surface if a content-injection vulnerability is exploited. func securityHeaders(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { h := w.Header() @@ -554,6 +557,7 @@ func securityHeaders(next http.Handler) http.Handler { h.Set("X-Frame-Options", "DENY") h.Set("Strict-Transport-Security", "max-age=63072000; includeSubDomains") h.Set("Referrer-Policy", "no-referrer") + h.Set("Permissions-Policy", "camera=(), microphone=(), geolocation=(), payment=()") next.ServeHTTP(w, r) }) } diff --git a/internal/ui/ui_test.go b/internal/ui/ui_test.go index 7b48050..c23b026 100644 --- a/internal/ui/ui_test.go +++ b/internal/ui/ui_test.go @@ -79,6 +79,7 @@ func assertSecurityHeaders(t *testing.T, h http.Header, label string) { {"X-Frame-Options", "DENY"}, {"Strict-Transport-Security", "max-age="}, {"Referrer-Policy", "no-referrer"}, + {"Permissions-Policy", "camera=()"}, } for _, c := range checks { val := h.Get(c.header)