Heavy security and file splitting
CI / Go Tests (push) Successful in 15s
CI / Build (push) Successful in 9s
Format / gofmt (push) Successful in 7s
Release Artifacts / Validate release tag (push) Successful in 2s
Release Artifacts / Build and release executables (push) Successful in 15s
Release Artifacts / Build and release Docker image (push) Successful in 28s
CI / Go Tests (push) Successful in 15s
CI / Build (push) Successful in 9s
Format / gofmt (push) Successful in 7s
Release Artifacts / Validate release tag (push) Successful in 2s
Release Artifacts / Build and release executables (push) Successful in 15s
Release Artifacts / Build and release Docker image (push) Successful in 28s
This commit is contained in:
@@ -321,3 +321,60 @@ func TestAccessLogMiddlewareOnlyAllowsConfiguredRoutes(t *testing.T) {
|
||||
t.Fatalf("expected access log for allowed route, got %q", buf.String())
|
||||
}
|
||||
}
|
||||
|
||||
// TestSecurityHeadersMiddlewareSetsDefaults verifies the new middleware sets expected headers
|
||||
// (X-Content-Type-Options, Referrer, CSP, HSTS conditional, etc.) on wrapped responses.
|
||||
func TestSecurityHeadersMiddlewareSetsDefaults(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
next := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write([]byte("ok"))
|
||||
})
|
||||
|
||||
// HSTS enabled (default)
|
||||
handler := SecurityHeadersMiddleware(true, next)
|
||||
req := httptest.NewRequest(http.MethodGet, "/anything", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
handler.ServeHTTP(rec, req)
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("status=%d want 200", rec.Code)
|
||||
}
|
||||
if got := rec.Header().Get("X-Content-Type-Options"); got != "nosniff" {
|
||||
t.Fatalf("X-Content-Type-Options=%q want nosniff", got)
|
||||
}
|
||||
if got := rec.Header().Get("Referrer-Policy"); got != "strict-origin-when-cross-origin" {
|
||||
t.Fatalf("Referrer-Policy=%q want strict-origin-when-cross-origin", got)
|
||||
}
|
||||
if got := rec.Header().Get("X-Frame-Options"); got != "DENY" {
|
||||
t.Fatalf("X-Frame-Options=%q want DENY", got)
|
||||
}
|
||||
hsts := rec.Header().Get("Strict-Transport-Security")
|
||||
if !strings.Contains(hsts, "max-age=31536000") {
|
||||
t.Fatalf("HSTS (enabled)=%q missing max-age", hsts)
|
||||
}
|
||||
csp := rec.Header().Get("Content-Security-Policy")
|
||||
if csp == "" || !strings.Contains(csp, "default-src 'self'") || !strings.Contains(csp, "frame-ancestors 'none'") {
|
||||
t.Fatalf("CSP=%q missing required", csp)
|
||||
}
|
||||
pp := rec.Header().Get("Permissions-Policy")
|
||||
if !strings.Contains(pp, "camera=()") {
|
||||
t.Fatalf("Permissions-Policy=%q", pp)
|
||||
}
|
||||
if ct := rec.Header().Get("Content-Type"); ct != "text/plain" {
|
||||
t.Fatalf("Content-Type was overwritten? got %q", ct)
|
||||
}
|
||||
|
||||
// HSTS disabled
|
||||
handlerNoHSTS := SecurityHeadersMiddleware(false, next)
|
||||
rec2 := httptest.NewRecorder()
|
||||
handlerNoHSTS.ServeHTTP(rec2, req)
|
||||
if hsts2 := rec2.Header().Get("Strict-Transport-Security"); hsts2 != "" {
|
||||
t.Fatalf("HSTS (disabled) should be absent, got %q", hsts2)
|
||||
}
|
||||
// other headers still present
|
||||
if got := rec2.Header().Get("X-Content-Type-Options"); got != "nosniff" {
|
||||
t.Fatalf("X-Content-Type-Options (no hsts)=%q want nosniff", got)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user