Security headers: the five that matter most
The HTTP security headers space has a lot of folklore around it. A scanner gives you an F, you turn on five headers, the scanner gives you an A, and your security posture is mostly unchanged. Some headers genuinely reduce risk. Others are theatre. Here is what we ship on production sites.
1. Content-Security-Policy
CSP is by far the most powerful and the most underused. A reasonable CSP defends against the entire XSS class of bug — the most common vulnerability category on the web — and lets you control which scripts, styles, and frames can load on your pages.
The cost is real. CSP requires discipline: a script-src that does not include unsafe-inline, a nonce-based or hash-based policy for inline scripts, and an active relationship with the third-party scripts on your page. But of all the headers, this is the one that genuinely moves the needle. Worth the investment.
2. Strict-Transport-Security
HSTS forces browsers to use HTTPS for your domain even when an attacker tries to downgrade the connection. Set it with max-age of at least one year and includeSubDomains. Add preload once you are confident, and submit to the HSTS preload list.
3. X-Content-Type-Options: nosniff
A one-liner that prevents browsers from second-guessing your Content-Type header. Costs nothing, eliminates a small but real class of bug.
4. Referrer-Policy
strict-origin-when-cross-origin is a sensible default. It avoids leaking the full URL (which often contains identifiers, tokens, or sensitive paths) to third-party domains while preserving useful referrer information for analytics.
5. Permissions-Policy
Lock down features your site does not use — camera, microphone, geolocation, FLoC, USB, payment. If a compromised third-party script tries to ask for them, the browser refuses on your behalf. Cheap to set, useful in defense in depth.
The ones that are mostly theatre
X-XSS-Protection has been a no-op in modern browsers for years. X-Frame-Options has been superseded by CSP's frame-ancestors. Expect-CT is deprecated. Setting any of these gives you a green check on a scanner without changing your security posture.
The harder follow-on
These five headers are the easy part. The harder work is everything they do not prevent: authentication bugs, authorisation bugs, business logic bugs, dependency vulnerabilities. Headers are a thin layer of defense; the real work is below the line. Don't let an A on a scanner give you false confidence.