Security Headers
HTTP security headers are response headers that tell the browser how to behave defensively — what content to load, whether to allow framing, and when to force HTTPS. They're one of the highest-leverage hardening steps available: a few lines of configuration that mitigate whole classes of attacks.
They're a backstop, not a substitute for fixing root causes, but a strong header set turns many would-be exploits into non-events.
TL;DR
- Use Content-Security-Policy to constrain what can load and run (XSS defense).
- Use HSTS to force HTTPS and block SSL-stripping.
- Set X-Frame-Options /
frame-ancestorsto prevent clickjacking. - Add X-Content-Type-Options: nosniff and a sane Referrer-Policy.
- Roll CSP out in report-only mode first, then enforce.
Quick Example
In Express, Helmet sets a strong baseline of headers in one line:
Then tighten individual policies (especially CSP) for your app's needs.
Core Concepts
The essential headers
Content-Security-Policy (CSP)
The most powerful and most complex header. It allowlists where scripts, styles, images, and connections may come from, and can block inline scripts — the main XSS vector. Start permissive in report-only mode, watch violations, then tighten. See XSS.
HSTS
Strict-Transport-Security makes the browser remember to use HTTPS, preventing downgrade attacks. Pair it with a strong TLS setup — see HTTPS & TLS.
Best Practices
Configure Helmet explicitly
Or set them at the edge (Nginx)
Roll CSP out safely
Common Mistakes
Allowing inline scripts in CSP
Enforcing a brand-new CSP straight away
A strict CSP almost always breaks something on first deploy. Ship it reportOnly first, fix the violations, then enforce.
Setting headers on some responses only
Apply headers globally (middleware or edge), not per-route — gaps are exactly where attacks land. Note X-XSS-Protection is deprecated; rely on CSP instead.
Testing
Scan your live site to confirm coverage:
- securityheaders.com
- Mozilla Observatory
- Lighthouse "Best Practices" audit in Chrome DevTools
FAQ
Which security headers are most important?
Content-Security-Policy and Strict-Transport-Security deliver the most protection (XSS and transport downgrade). After those, add X-Content-Type-Options: nosniff, clickjacking protection (frame-ancestors/X-Frame-Options), and a Referrer-Policy.
Should I use X-Frame-Options or CSP frame-ancestors?
Prefer CSP frame-ancestors — it's the modern, more flexible replacement. Keep X-Frame-Options: DENY alongside it for older browsers that don't support CSP framing directives.
Why is my CSP breaking the site?
Usually because real scripts, styles, or API calls aren't in the allowlist, or the app relies on inline scripts. Run in report-only mode, read the violation reports, and add the legitimate sources (or refactor inline scripts to use nonces).
Is Helmet enough on its own?
Helmet gives a solid baseline, but the default CSP is intentionally generic. Tailor the CSP directives to your actual asset and API origins to get real protection.
Related Topics
- Cross-Site Scripting (XSS) — What CSP is primarily defending against
- HTTPS & TLS — The transport layer HSTS enforces
- CSRF — Cookie hardening that complements these headers
- API Security — Headers as one layer of defense in depth