HTTP security headers: the complete hardening guide
If you want the best security return for the least effort on a website, HTTP security headers are it. They’re configured once (at your web server, framework, or CDN), apply to every response automatically, and instruct the browser to enforce a set of protective behaviours that blunt entire classes of attack.
This guide walks through every header that matters in 2026: what it does, which attack it stops, and the value to set. You can check your own site against all of them for free with our HTTP Header Analyzer as you read.
What security headers are (and aren’t)
A security header is a response header that tells the browser to turn on a defensive behaviour: “only run scripts from my own origin,” “always use HTTPS,” “don’t let other sites frame me.” The browser enforces the instruction on the client side.
One thing to be clear about: headers are defence in depth, not a substitute for fixing vulnerabilities at the source. A Content-Security-Policy limits the damage of a cross-site scripting bug, but you should still eliminate the bug. Think of headers as the seatbelts and airbags of your site: essential, but not a reason to drive recklessly.
With that framing, here are the headers that earn their place.
Content-Security-Policy (CSP): the heavy hitter
CSP is the most powerful security header and also the hardest to get right. It tells the browser exactly which sources of content (scripts, styles, images, frames) are allowed to load and execute. MDN’s Content-Security-Policy reference documents every directive, and it is worth keeping open the first few times you write one. A strict CSP can neutralise cross-site scripting entirely: even if an attacker injects a <script>, the browser refuses to run it because it doesn’t come from an approved source.
A reasonable strict starting point:
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'
The single most important rule: avoid 'unsafe-inline' in script-src. It’s the most common way sites accidentally throw away most of their CSP protection, because it re-permits exactly the inline scripts that XSS relies on. Modern strict CSPs use nonces or hashes to allow specific trusted inline scripts instead.
CSP takes tuning (you need to know every resource your site legitimately loads), which is why our analyzer includes a dedicated CSP linter to flag weak directives like unsafe-inline and overly broad sources.
Strict-Transport-Security (HSTS): enforce HTTPS
HSTS tells the browser to only ever connect to your site over HTTPS, for a set period, even if the user types http:// or follows an old insecure link. This closes the window for protocol-downgrade and man-in-the-middle attacks that depend on intercepting that first plaintext request.
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
max-age=31536000: remember the HTTPS-only rule for one year.includeSubDomains: apply it to every subdomain too.preload: allows inclusion in browsers’ built-in HSTS preload list, so the very first request is protected as well.
Only enable includeSubDomains and preload once you’re certain every subdomain supports HTTPS, since it’s a strong, sticky commitment. Pair HSTS with a valid, well-configured certificate. Check yours with the SSL/TLS Checker.
X-Content-Type-Options: stop MIME sniffing
X-Content-Type-Options: nosniff
Browsers sometimes try to guess (“sniff”) the type of a resource rather than trusting the declared Content-Type. That guessing can be abused to make the browser treat an uploaded file as executable script. nosniff disables the guessing and forces the browser to honour the declared type. It’s a one-line, no-downside header. Set it everywhere.
Clickjacking defence: frame-ancestors and X-Frame-Options
Clickjacking loads your site invisibly inside an attacker’s page and tricks users into clicking things they can’t see: approving a transaction, changing a setting. Two headers defend against it:
Content-Security-Policy: frame-ancestors 'self'
X-Frame-Options: SAMEORIGIN
The modern control is CSP’s frame-ancestors directive, which precisely specifies which origins may frame your site. X-Frame-Options is the older, coarser header kept for compatibility with legacy browsers. Use frame-ancestors as the real control and keep X-Frame-Options alongside it.
Referrer-Policy: control what you leak
Referrer-Policy: strict-origin-when-cross-origin
When a user navigates from your site to another, the browser sends a Referer header telling the destination where they came from, which can leak sensitive path or query data in your URLs. strict-origin-when-cross-origin sends the full URL to same-origin destinations but only the bare origin to other sites, and nothing when downgrading from HTTPS to HTTP. A sensible privacy-preserving default.
Permissions-Policy: disable features you don’t use
Permissions-Policy: camera=(), microphone=(), geolocation=()
Permissions-Policy (formerly Feature-Policy) lets you switch off powerful browser features your site doesn’t need: camera, microphone, geolocation, and more. Disabling unused features shrinks the attack surface: if your site never uses the camera, denying it means an injected script can’t try to either.
Cookie security flags: protect the session
Not headers in the strict sense, but set via the Set-Cookie header, and critical enough that no hardening guide is complete without them:
Set-Cookie: session=...; HttpOnly; Secure; SameSite=Lax
HttpOnly: JavaScript cannot read the cookie, so a successful XSS payload can’t simply steal the session token viadocument.cookie.Secure: the cookie is only ever sent over HTTPS, never in plaintext.SameSite=Lax(orStrict): the cookie isn’t sent on cross-site requests, which mitigates cross-site request forgery (CSRF).
Together these three flags dramatically harden session cookies against the most common session-theft techniques. Our analyzer includes a cookie audit that checks each of these on every cookie your site sets.
Headers you should not rely on
Security advice ages, and some once-recommended headers are now obsolete:
X-XSS-Protectioncontrolled a legacy browser XSS filter that modern browsers have removed and that could itself introduce issues. Set it to0or omit it, and rely on CSP instead. If a scanner still demands it, the scanner is outdated.Public-Key-Pins(HPKP) is deprecated and dangerous: a misconfiguration could lock users out of your site. Don’t use it.
Knowing what not to set is as valuable as knowing what to set.
A practical rollout plan
Adding headers carelessly can break a site: a too-strict CSP can block your own scripts. Roll them out deliberately:
- Start with the safe, no-downside headers:
X-Content-Type-Options: nosniff,Referrer-Policy,X-Frame-Options/frame-ancestors, and the cookie flags. - Add HSTS once you’ve confirmed HTTPS works everywhere, starting with a shorter
max-agebefore committing to a year andpreload. - Tackle CSP last and carefully. Build it up from
default-src 'self', add the specific sources your site genuinely needs, test thoroughly, and use report-only mode first to catch what it would break before you enforce it. - Scan, fix, re-scan. Run your site through the HTTP Header Analyzer, work down the prioritised list of gaps with its platform-specific fix snippets, then re-scan to confirm.
Key takeaways
- Security headers are cheap, high-impact hardening: configured once, enforced by the browser on every response.
- CSP is the most powerful (avoid
unsafe-inline), HSTS enforces HTTPS, and the cookie flags protect sessions. - Simple wins like
nosniff,frame-ancestors,Referrer-Policy, andPermissions-Policyadd up fast. - Some old headers (
X-XSS-Protection, HPKP) should no longer be used. - Roll out carefully, especially CSP, and verify with a scanner.
Headers won’t fix a broken application on their own, but they turn many would-be catastrophes into non-events. For the effort involved, nothing else on your security checklist pays off as reliably.
For a second opinion on your configuration, securityheaders.com grades any public site in seconds, Mozilla’s SSL Configuration Generator produces a matching TLS setup for your web server, and Qualys SSL Labs audits the certificate chain and cipher suites behind it. The underlying HTTP semantics are specified in RFC 9110.
Check your site now with the free HTTP Header Analyzer, learn how CSP stops attacks in the XSS guide, and see the bigger picture in the OWASP Top 10 breakdown.