From 61875201f9e4bb1ac5d63027b1c6740038ec24c2 Mon Sep 17 00:00:00 2001 From: Kharec Date: Wed, 6 May 2026 20:13:56 +0200 Subject: [PATCH] fix(middleware): configurable Swagger CSP, log CSP nonce errors, drop X-XSS-Protection --- internal/middleware/security_headers.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/internal/middleware/security_headers.go b/internal/middleware/security_headers.go index 58fd5fa..7da9d79 100644 --- a/internal/middleware/security_headers.go +++ b/internal/middleware/security_headers.go @@ -5,12 +5,21 @@ import ( "crypto/rand" "encoding/base64" "fmt" + "log" "net/http" "strings" ) const CSPNonceKey contextKey = "csp_nonce" +type SecurityHeadersConfig struct { + RelaxSwaggerCSP bool +} + +func DefaultSecurityHeadersConfig() SecurityHeadersConfig { + return SecurityHeadersConfig{RelaxSwaggerCSP: true} +} + func GenerateCSPNonce() (string, error) { nonceBytes := make([]byte, 16) if _, err := rand.Read(nonceBytes); err != nil { @@ -27,15 +36,18 @@ func GetCSPNonceFromContext(ctx context.Context) string { } func SecurityHeadersMiddleware() func(http.Handler) http.Handler { + return SecurityHeadersMiddlewareWithConfig(DefaultSecurityHeadersConfig()) +} + +func SecurityHeadersMiddlewareWithConfig(cfg SecurityHeadersConfig) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("X-Content-Type-Options", "nosniff") w.Header().Set("X-Frame-Options", "DENY") - w.Header().Set("X-XSS-Protection", "1; mode=block") w.Header().Set("Referrer-Policy", "strict-origin-when-cross-origin") isSwaggerRoute := strings.HasPrefix(r.URL.Path, "/swagger") - if isSwaggerRoute { + if isSwaggerRoute && cfg.RelaxSwaggerCSP { csp := "default-src 'self'; " + "script-src 'self' 'unsafe-inline' 'unsafe-eval'; " + "style-src 'self' 'unsafe-inline'; " + @@ -51,7 +63,7 @@ func SecurityHeadersMiddleware() func(http.Handler) http.Handler { } else { nonce, err := GenerateCSPNonce() if err != nil { - + log.Printf("middleware security headers: CSP nonce: %v", err) nonce = "" } @@ -72,7 +84,6 @@ func SecurityHeadersMiddleware() func(http.Handler) http.Handler { csp = "script-src 'self' 'nonce-" + nonce + "'; " + "style-src 'self' 'nonce-" + nonce + "'; " + csp } else { - csp = "script-src 'self'; " + "style-src 'self'; " + csp }