HTTP Security Headers Table
| Header | What it prevents | Field note |
|---|---|---|
Content-Security-Policy | XSS, injection, inline scripts | The most powerful header - also the hardest to deploy |
Strict-Transport-Security | HTTP downgrade attacks | max-age=31536000; includeSubDomains; preload |
X-Content-Type-Options: nosniff | MIME-type sniffing | One line, zero downside - always set it |
X-Frame-Options: DENY | Clickjacking via iframe | Legacy but still checked - CSP frame-ancestors supersedes |
Referrer-Policy: strict-origin | Referer leakage | strict-origin-when-cross-origin is the modern default |
Permissions-Policy | Camera, mic, geolocation access | Declarative - the successor to Feature-Policy |
Cross-Origin-Opener-Policy | Cross-window attacks | Isolates your browsing context from other origins |
Security headers are the server's defense-in-depth: HTTP response headers that instruct the browser to enforce security policies. The table below is the working seven - from CSP (the XSS dam) to Cross-Origin-Opener-Policy (the isolation layer) - with the deployment patterns that prevent them from breaking your own site.
Bottom line: CSP is the hardest to deploy (legacy inline scripts break) but the highest value - start with Content-Security-Policy-Report-Only to discover violations before enforcing. The rest are one-liners with no downside: X-Content-Type-Options: nosniff costs nothing and closes MIME-sniffing attacks; Strict-Transport-Security forces HTTPS and prevents downgrade attacks.
The honest part: security headers are NOT a replacement for input validation and output encoding. They are defense-in-depth - the second line of defence that limits the damage when the first line fails. CSP limits what injected scripts can do; it does not prevent injection. HSTS prevents downgrade attacks; it does not fix an HTTP-only deployment.
How to use
- Start CSP in report-only mode: Content-Security-Policy-Report-Only with a report-uri discovers violations before enforcement.
- Add the one-liners first: X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Referrer-Policy - zero downside, immediate benefit.
- Deploy HSTS with a short max-age first, then increase - once you send it, browsers cache it and you cannot un-send it.
Frequently asked questions
What does Content-Security-Policy actually prevent?
CSP controls what resources the page can load and execute - it is the XSS dam. The default-src 'self' baseline blocks inline scripts, eval, and loading scripts from unapproved origins. Even if an attacker injects a <script> tag, CSP prevents it from executing. The deployment challenge: legacy inline scripts and inline event handlers (onclick=) break under CSP - the migration is moving to external scripts and addEventListener.
Why is HSTS important if I already redirect HTTP to HTTPS?
Because the redirect happens AFTER the initial HTTP request - and that first unencrypted request is the window for downgrade attacks (man-in-the-middle strips the HTTPS redirect). Strict-Transport-Security tells the browser to NEVER connect over HTTP for this domain - after the first HTTPS visit, the browser refuses HTTP automatically. The preload list takes it further: browsers ship with your domain pre-loaded as HTTPS-only.
What is the difference between X-Frame-Options and CSP frame-ancestors?
They prevent the same attack (clickjacking via iframe embedding) but X-Frame-Options is the legacy header with only two values (DENY and SAMEORIGIN), while CSP frame-ancestors is the modern replacement with URI-level control. Set both: X-Frame-Options: DENY for older browsers, Content-Security-Policy: frame-ancestors 'none' for modern ones. Browsers that support both use the CSP version.
How do I deploy security headers without breaking my site?
Gradually. Start with the zero-risk headers (nosniff, Referrer-Policy, Permissions-Policy) - they have no effect on existing functionality. Add HSTS with a short max-age and increase it. Deploy CSP in report-only mode first, review the violation reports, fix the inline scripts and unapproved sources, then switch to enforcement. The report-only mode is the key: it tells you what WILL break before it breaks.