HTTP Security Headers — Complete Guide
Response headers are the cheapest defense-in-depth layer you own: the browser reads them on every navigation and applies policy before your JavaScript runs. Here’s what teams actually ship, how those headers get misconfigured, and copy-paste snippets that fix them on common stacks.
What each header does
HSTS pins HTTPS for a host so bookmarks and typed HTTP URLs upgrade instead of falling through cleartext. You want a sane max-age, includeSubDomains only when every subdomain is TLS-clean, and preload only after you mean it.
CSP lists where scripts, styles, images, frames, and connections may load from. It’s the main XSS mitigation for modern apps when you move off unsafe-inline toward nonces or hashes.
X-Frame-Options (or frame-ancestors in CSP) blocks clickjacking by refusing to render your site inside foreign iframes.
X-Content-Type-Options: nosniff stops the browser from MIME-sniffing responses into executable contexts—especially important for user-upload directories and static hosts that serve text/plain wrong.
Referrer-Policy trims what lands in the Referer header so query tokens and internal paths do not leak to analytics or OAuth intermediaries.
Permissions-Policy disables powerful features (camera, geolocation, payment) until a frame explicitly needs them.
COOP and COEP isolate your browsing context. Pair them when you rely on SharedArrayBuffer or hardened Spectre-related modes; mis-sized CORP on third-party assets is the usual failure mode.
Patterns that break in production
- HSTS with
includeSubDomainswhile one legacy box still serves HTTP—users brick themselves until max-age expires. - CSP copied from a tutorial with
https:or overly broad*sources—works until someone adds a JSONP endpoint you forgot. - Duplicate header lines where the stricter value loses depending on CDN merge order.
- Framing policy missing on login pages while CSP allows
frame-ancestors *on the API only. - COEP
require-corpwithoutCross-Origin-Resource-Policyon CDNs—assets silently fail.
Nginx
CSP belongs in one line you can iterate—start report-only, then enforce:
Apache (mod_headers)
Vercel (vercel.json)
Edge platforms merge headers from multiple layers—middleware, vercel.json, and upstream. When you see duplicated Content-Security-Policy values in DevTools, check whether both the framework and the edge are emitting policy; browsers intersect or favor the strictest interpretation depending on directive.
Permissions-Policy sample
Start deny-by-default for sensors you do not use, then open specific origins if a payment or maps iframe needs them:
Operational habit
Scan your live deployment, then diff what you ship versus what your HTML actually loads—that is fewer iterations than guessing in staging. Store the header block in version control next to infra code so reviews catch regressions when someone bumps a CDN preset. HeadersFixer reads your site URL and mirrors the stack tabs you already deploy—paste, reload, and verify Security panel before closing the ticket.