Six HTTP response headers get recommended in almost every "harden your site" checklist, usually as a flat list with no explanation of what each one actually defends against. Some of them close a real, exploitable gap. A couple are closer to defense-in-depth. Here's what each one does, concretely, and what it doesn't.
Strict-Transport-Security (HSTS)
What it stops: SSL-stripping. Without HSTS, every visit to your site starts as a plain HTTP request that your server then redirects to HTTPS — and that first request is interceptable on a hostile network (open WiFi, a compromised router). An attacker in that position can strip the redirect and keep the victim on HTTP indefinitely.
What it doesn't do: protect the very first visit, unless you've submitted the domain to browsers' HSTS preload list — max-age only kicks in after the browser has already seen the header once.
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Reference: RFC 6797
Content-Security-Policy (CSP)
What it stops: the execution half of XSS. Even if an attacker manages to inject a <script> tag or an inline event handler into your page, a well-scoped CSP stops the browser from running it, because the injected content doesn't come from an allow-listed origin.
What it doesn't do: stop the injection itself — CSP is a blast-radius control, not an input-sanitization substitute. It's also the header most likely to break something in production if you deploy it without a Report-Only phase first.
Reference: MDN — Content-Security-Policy
X-Frame-Options
What it stops: clickjacking — an attacker embedding your login/payment/admin page in an invisible iframe on their own site and tricking a user into clicking something that actually submits on your page.
What it doesn't do: anything CSP's frame-ancestors directive can't already do better (allow-list specific origins instead of an all-or-nothing rule). X-Frame-Options is the older, blunter tool, but it's still worth sending since frame-ancestors support isn't universal.
Reference: MDN — X-Frame-Options
X-Content-Type-Options
What it stops: MIME-sniffing — some browsers historically inspected response bytes and guessed the content type even when the server's Content-Type disagreed, which let an uploaded "image" get reinterpreted and executed as HTML/JS.
What it doesn't do: matter as much as it used to. Modern browsers sniff far less aggressively. It's still a one-line, zero-downside header with no legitimate reason to skip.
Referrer-Policy
What it stops: leaking your URLs (which often carry session tokens, search terms, or internal IDs in the query string) to third-party sites and analytics tools via the Referer header.
What it doesn't do: matter much if your URLs never carry sensitive query-string data in the first place — but you usually can't guarantee that across every page and every future contributor.
Permissions-Policy
What it stops: a compromised third-party script or malicious iframe ad from invoking a permission prompt (camera, microphone, geolocation) for a capability your page never intended to use.
What it doesn't do: fix a vulnerability directly — it's defense-in-depth, which is also why it's usually the lowest-severity item on a scan report.
Checking your own site
I maintain Nivaronix, a free scanner that checks all six of these (plus SSL/TLS, DNS/DNSSEC/CAA, and SPF/DMARC) and tells you exactly which are missing and why. No signup needed for a single scan. Full breakdown of each header, with server config snippets for Nginx/Apache/Cloudflare, is in the security headers guide.
To be clear about what it isn't: it's a configuration/posture checker, not a penetration test, and it doesn't do vulnerability/CVE scanning or malware detection. If you want that, you want a different tool — this one's scope is "is your config missing the stuff that stops these specific, well-understood attack classes."
What's on your own header checklist that I didn't cover here?
Top comments (0)