DEV Community

Pravin Gyawali
Pravin Gyawali

Posted on

What security headers actually stop (and which ones don't matter much)

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
Enter fullscreen mode Exit fullscreen mode

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)