package test import ( "RenewCMS/api/handlers/frontend" "RenewCMS/api/middleware" "net/http" "net/http/httptest" "strings" "testing" ) func serveWithSecurityHeaders(hsts bool) http.Header { handler := middleware.SecurityHeaders(hsts)(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) })) rec := httptest.NewRecorder() handler.ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/", nil)) return rec.Result().Header } func TestSecurityHeadersAlwaysSetBaseline(t *testing.T) { headers := serveWithSecurityHeaders(false) expected := map[string]string{ "X-Content-Type-Options": "nosniff", "X-Frame-Options": "DENY", "Referrer-Policy": "strict-origin-when-cross-origin", "Cross-Origin-Opener-Policy": "same-origin", } for name, want := range expected { if got := headers.Get(name); got != want { t.Errorf("expected %s %q, got %q", name, want, got) } } } func TestSecurityHeadersContentSecurityPolicy(t *testing.T) { csp := serveWithSecurityHeaders(false).Get("Content-Security-Policy") for _, directive := range []string{ "default-src 'self'", "script-src 'self' 'wasm-unsafe-eval';", "object-src 'none'", "base-uri 'self'", "frame-ancestors 'none'", } { if !strings.Contains(csp, directive) { t.Errorf("expected CSP to contain %q, got %q", directive, csp) } } if strings.Contains(csp, "'unsafe-eval'") || strings.Contains(csp, "script-src 'self' 'unsafe-inline'") { t.Errorf("script-src must not allow unsafe sources, got %q", csp) } } func TestAllowInlineScriptsHashesOnlyInlineScripts(t *testing.T) { policy := "default-src 'self'; script-src 'self'; object-src 'none'" html := []byte(`
`) got := frontend.AllowInlineScripts(policy, html) if !strings.Contains(got, "script-src 'self' 'sha256-") || strings.Count(got, "sha256-") != 1 { t.Errorf("expected exactly one inline hash in script-src, got %q", got) } if !strings.Contains(got, "; object-src 'none'") { t.Errorf("expected other directives untouched, got %q", got) } } func TestAllowInlineScriptsLeavesPolicyWithoutInlineScripts(t *testing.T) { policy := "script-src 'self'" html := []byte(``) if got := frontend.AllowInlineScripts(policy, html); got != policy { t.Errorf("expected policy unchanged, got %q", got) } } func TestSecurityHeadersHSTSOnlyWhenEnabled(t *testing.T) { if got := serveWithSecurityHeaders(false).Get("Strict-Transport-Security"); got != "" { t.Errorf("expected no HSTS header, got %q", got) } if got := serveWithSecurityHeaders(true).Get("Strict-Transport-Security"); got != "max-age=31536000" { t.Errorf("expected HSTS max-age=31536000, got %q", got) } }