HTTP security headers
Overview
When a browser loads a web page, the server returns the content plus a set of response headers — instructions that tell the browser how to behave. Security headers are the subset of those instructions that harden the browser's behavior: e.g. "only connect over HTTPS," "don't let other sites frame me," "don't guess file types."
Why they matter
Security headers are passive defenses. They cost nothing to send, are invisible to users, and replace the browser's permissive defaults with safer ones. On their own, a missing header is rarely directly exploitable — the value appears when another weakness exists. The right headers shrink the blast radius: they can turn an XSS bug into a contained issue instead of full session theft, block clickjacking, and stop protocol downgrades. They're defense-in-depth, not a primary control.
The common headers
| Header | Defends against | Typical value |
|---|---|---|
| Strict-Transport-Security (HSTS) | TLS downgrade / SSL-strip | max-age=31536000; includeSubDomains; preload |
| Content-Security-Policy (CSP) | XSS, data injection | default-src 'self'; object-src 'none'; frame-ancestors 'none' (tailored per app) |
| X-Frame-Options | Clickjacking | DENY (or SAMEORIGIN) |
| X-Content-Type-Options | MIME-sniffing | nosniff |
| Referrer-Policy | URL/token leakage via Referer | strict-origin-when-cross-origin |
| Permissions-Policy | Unwanted use of browser features | camera=(), microphone=(), geolocation=() |
| Cross-Origin-Opener-Policy (COOP) | Tab-takeover via window.open | same-origin |
| Cross-Origin-Resource-Policy (CORP) | Cross-site reads of resources | same-origin or same-site |
| Cross-Origin-Embedder-Policy (COEP) | Spectre-class side-channels | require-corp |
| Clear-Site-Data | Stale data on shared devices | "cache", "cookies", "storage" (logout only) |
| Content-Type | Response-type confusion | application/json; charset=utf-8 (on JSON) |
The "easy" ones vs. the ones that need care
Most of these are safe to deploy with the standard value and rarely break anything: X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, COOP, CORP. The four below need thought:
- HSTS — hard to reverse. Once a browser sees it, it refuses HTTP for the whole
max-age, andpreloadis effectively permanent. Verify HTTPS works everywhere first; start with a shortmax-age; only submit to the preload list once you're certain. WithincludeSubDomains, any non-HTTPS subdomain becomes unreachable. - CSP — the strongest header but the highest-maintenance. A strict
script-srcallowlist must be updated whenever a new third-party script is added. Always roll out inContent-Security-Policy-Report-Onlymode first, collect violations, then enforce. Apps with many third-party scripts often accept a looser policy or stay in report-only. - COEP (
require-corp) — only needed for cross-origin isolation features (SharedArrayBuffer, high-res timers). It forces every cross-origin resource to opt in or be blocked, which breaks fonts/images/scripts on most sites. Usually skipped unless specifically required. - Clear-Site-Data — the
"cookies"directive clears cookies for the entire registered domain and all subdomains, and"storage"only clears the responding origin. On multi-subdomain or split frontend/API setups it often clears the wrong thing or too much, so it needs careful, logout-only scoping — or is skipped.
Where to set them
They can be set at the application layer, but it's usually cleanest to set them at the CDN / edge (e.g. Cloudflare, CloudFront) so every response is covered without code changes. The two exceptions: Content-Type belongs in the app (the app knows each response's real type), and Clear-Site-Data must be scoped to the logout response only.
How to verify
- securityheaders.com and Mozilla / MDN Observatory — give a letter grade and flag missing headers. Target at least an A.
- Raw check (curl/PowerShell) — the only way to confirm all headers by name, since the graders only score a subset.
Note: no single online grader checks every header above. securityheaders.com and Observatory score the high-impact subset; the full list is best confirmed with a direct header dump.