Core security response headers are configured
Why it matters
Three response headers carry most of the browser-enforced defenses that make modern web apps resistant to common attacks: Strict-Transport-Security (HSTS) prevents TLS-strip downgrades, Content-Security-Policy (CSP) caps the blast radius of any XSS bug, and Referrer-Policy stops URLs containing tokens or session identifiers from leaking to third parties in referrer strings. AuditBuffet's own production telemetry across 37 first-run security-headers audits shows HSTS missing in 76% of scans, CSP missing in 65%, and Referrer-Policy missing in 54% — the majority of AI-generated sites ship with all three absent. The attacker's path is concrete: without HSTS, a user on a hostile Wi-Fi network can be downgraded to HTTP and have their session cookie stolen; without CSP, a single reflected-XSS bug becomes a full account-takeover via arbitrary script execution; without Referrer-Policy, password-reset links, magic-login tokens, and OAuth callbacks leak into analytics pipelines and third-party ad networks. GDPR Article 32 (appropriate technical measures) treats referrer leakage of personal identifiers as a reportable data incident.
Severity rationale
High because each missing header leaves a distinct browser-level defense un-enforced — the composite exposure spans network-layer downgrade attacks, XSS amplification, and session-token leakage through referrers simultaneously.
Remediation
Configure all three headers in next.config.ts (Next.js), middleware.ts, or vercel.json:
// next.config.ts
export default {
async headers() {
return [{
source: '/:path*',
headers: [
{ key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains; preload' },
{ key: 'Content-Security-Policy', value: "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'" },
{ key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
],
}];
},
};
Start with a permissive CSP and tighten over time — even a loose CSP is better than none, and having the header present means the browser enforces directive limits where you have set them. For a full header-hardening pass including Permissions-Policy, X-Content-Type-Options, Cross-Origin-Opener-Policy, nonce-based CSP, and SRI coverage, run the security-headers and security-headers-ii Pro audits.
Detection
- ID:
security-headers-present - Severity:
high - What to look for: Search for response-header config in: (a)
next.config.{ts,js,mjs}—headers()async export returning[{ source, headers: [{ key, value }, ...] }]; (b)middleware.tswithNextResponse+.headers.set(...); (c)vercel.jsontop-levelheadersarray; (d) Astroastro.config.mjs, SvelteKithooks.server.ts, Remixentry.server.ts; (e) Express/Fastifyapp.use(helmet())orres.setHeader(...). From the union, check three headers: (1)Strict-Transport-Securitywithmax-age≥ 15552000 (6 months); (2)Content-Security-Policywith any non-empty value; (3)Referrer-Policyset to anything other thanunsafe-url. - Pass criteria: All three headers present and valid.
- Fail criteria: Any missing; HSTS
max-agebelow 15552000; Referrer-Policy =unsafe-url. Headers defined in a config the framework doesn't use (e.g.vercel.jsonin a non-Vercel deploy,middleware.tswhose matcher excludes live routes) do NOT count. CSP set todefault-src *; script-src * 'unsafe-inline' 'unsafe-eval'is functionally absent. - Skip (N/A) when: Not a web app — CLI, npm library, native-mobile, backend-only API whose responses never reach a browser. Quote
package.jsonmain/bin+ project structure. - Before evaluating, quote: Each header-configuration file (at least the
headers()export orheadersarray) + middleware matcher if present. - Report even on pass: Exact file path + exact values:
"All 3 in next.config.ts: HSTS max-age=63072000 includeSubDomains preload, CSP 'default-src self...', Referrer-Policy strict-origin-when-cross-origin". - Detail on fail:
"HSTS missing in next.config.ts, middleware.ts, vercel.json. CSP present but Referrer-Policy missing — add to headers() at next.config.ts:12". - Remediation:
Any non-empty CSP is better than none — tighten directives incrementally. For full coverage (Permissions-Policy, X-Content-Type-Options, COOP, nonce CSP, SRI), run// next.config.ts export default { async headers() { return [{ source: '/:path*', headers: [ { key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains; preload' }, { key: 'Content-Security-Policy', value: "default-src 'self'; script-src 'self' 'unsafe-inline'" }, { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' }, ]}]; }, };security-headers/security-headers-ii.
External references
- cwe · CWE-693 — Protection Mechanism Failure
- cwe · CWE-319 — Cleartext Transmission of Sensitive Information
- owasp:2021 · A05 — Security Misconfiguration
Taxons
History
- 2026-04-23·v1.0.0·Initial Phase 9.1 v3.1 Stack Scan promotion — production telemetry shows 76%/65%/54% first-run miss rates for HSTS/CSP/Referrer-Policy respectively.·by phase-9-1-stack-scan-v3-1