Skip to content
IsSafeSite
2 min readIsSafeSite Team

The 10 Most Common Security Header Mistakes (and How to Fix Them)

Security headers are the cheapest hardening you can ship — and the easiest to get subtly wrong. Here are the ten mistakes scanners flag most, with the exact fix for each.

HeadersHardeningCSP

HTTP response headers are the rare security control that costs a few lines of config and protects every visitor immediately. That is also why getting them wrong is so common: they are easy to copy-paste and hard to test. These are the ten issues that show up over and over in scan results.

1. No HSTS (or HSTS without the preload path)

Without Strict-Transport-Security, a single plaintext request can be intercepted before the HTTPS redirect. Set a long max-age and include subdomains:

Strict-Transport-Security: max-age=63072000; includeSubDomains; preload

Only add preload once every subdomain is HTTPS-only — it is hard to undo quickly.

2. A Content-Security-Policy that allows unsafe-inline

script-src 'unsafe-inline' re-opens the exact XSS hole CSP exists to close. Move to nonces or hashes:

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{random}'; object-src 'none'; base-uri 'self'

3. Shipping CSP in report-only mode forever

Content-Security-Policy-Report-Only is for the rollout phase. Plenty of sites leave it there for months, collecting reports while enforcing nothing. Use report-only to find violations, then switch to the enforcing header once it is quiet.

4. X-Frame-Options instead of frame-ancestors

X-Frame-Options is legacy and cannot express an allow-list. Prefer the CSP directive, which modern browsers honor:

Content-Security-Policy: frame-ancestors 'self'

5. Missing X-Content-Type-Options

Without X-Content-Type-Options: nosniff, a browser may MIME-sniff a response and execute something you served as text. It is a single header with no downside — always set it.

6. A dangerous or absent Referrer-Policy

The default leaks full URLs (including tokens in query strings) to third parties. A safe, broadly compatible choice:

Referrer-Policy: strict-origin-when-cross-origin

7. Permissions-Policy left at the browser default

If your app does not use the camera, microphone or geolocation, say so explicitly so a compromised script cannot either:

Permissions-Policy: camera=(), microphone=(), geolocation=()

8. Setting headers on HTML but not on the API

Headers applied by a frontend framework often miss API routes, redirects and error pages. Scanners test those paths directly. Set security headers at the edge — a reverse proxy, CDN or platform middleware — so coverage is uniform.

9. Conflicting headers from multiple layers

When both your app and your CDN set Content-Security-Policy, the browser may see two headers and apply the *intersection*, silently breaking features. Decide on one authoritative layer and remove the duplicates.

10. Caching sensitive responses

Authenticated pages and API responses with personal data should not be cacheable by shared proxies:

Cache-Control: no-store

Confirm with a re-scan

Headers interact, so change them in small batches and re-scan after each. If you are new to reading the results, start with How to Read a Website Security Scan Report; for the transport layer underneath these headers, see SSL/TLS Misconfigurations That Put Your Site at Risk. The full header check runs on every scan — see all checks on the features page.

Turn these checks into a scan report for your own site.

Run a free scan and get prioritized, actionable findings in about 30 seconds.

Scan my site

Keep reading