What Are Security Headers and Why They Matter
Security headers are HTTP response headers that instruct the browser how to treat your page — which scripts to trust, whether to force HTTPS, and how to handle framing and content types. They matter because they push defenses out of your server code and into the browser itself, neutralizing whole classes of attacks (clickjacking, protocol downgrade, MIME-sniffing, many XSS payloads) before they ever reach a user. Unlike a firewall or WAF, they add nothing to page weight and apply on every single request.
The core set most scanners inspect is a group of six response headers, each mapped to a specific attack:
- Strict-Transport-Security (HSTS) — forces HTTPS, blocks SSL-strip/downgrade
- Content-Security-Policy (CSP) — restricts script/style sources, kills most reflected XSS
- X-Frame-Options — prevents clickjacking via hidden iframes
- X-Content-Type-Options: nosniff — stops MIME-type confusion
- Referrer-Policy — prevents URL/token leakage to third parties
- Permissions-Policy — locks down camera, mic, and geolocation APIs
A practical point that raw checklists skip: presence is not the same as correctness. securityheaders.com reports each of these six headers as present or missing and drops your letter grade for every one that is absent (source: https://securityheaders.com/). But a header can be "present" and still worthless if its value is weak.
That is where a scoring scanner beats a simple presence check. Mozilla's HTTP Observatory awards full HSTS credit only when max-age is at least six months — 15,768,000 seconds (source: https://developer.mozilla.org/en-US/observatory). Set a shorter lifetime and a shallow tool still shows a green tick, while Observatory quietly deducts points.
My recommendation as a working method: run two scanners, not one. A presence-based tool such as securityheaders.com tells you what is missing, while a value-based scorer like Mozilla Observatory tells you whether what you have is actually strong enough (source: https://securityheaders.com/ and https://developer.mozilla.org/en-US/observatory). The gap between their verdicts is usually where the real misconfiguration hides.
Essential HTTP Security Headers Explained (CSP, HSTS, X-Frame-Options, etc.)
Below is a header-by-header breakdown written for people who actually have to fix the report a scanner spits out — not just read a glossary. Each header includes what it blocks, a value you can paste, and where it commonly goes wrong.
Content-Security-Policy (CSP)
CSP is the only header on this list that mitigates injected script rather than just tightening browser behavior. The practical trap: a policy is only as strong as its weakest directive, so default-src 'self'; script-src 'self' is worth more than a long policy that still contains 'unsafe-inline'.
- Start in report-only mode (
Content-Security-Policy-Report-Only) so you break nothing while collecting violations. - Use
frame-ancestors 'none'inside CSP — modern browsers treat it as the successor to X-Frame-Options, so setting it here covers clickjacking too. - Avoid
'unsafe-inline'and wildcards (*); they silently neutralize the whole policy.
Strict-Transport-Security (HSTS)
HSTS forces HTTPS on repeat visits, closing the SSL-stripping window on the first redirect. If you want the header accepted for the browser preload list, securityheaders.com flags it as preload-ready only when max-age is at least 31536000 seconds — one full year — and combined with includeSubDomains; preload (source: https://securityheaders.com/). Do not add preload casually: it is hard to reverse.
- Recommended value:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Frame-Options
Blocks your pages from being embedded in <iframe>/<frame> (clickjacking). It is effectively legacy — keep it only for old browsers and let CSP frame-ancestors do the real work.
- Use
DENYif the page is never framed, orSAMEORIGINif you frame it yourself.
X-Content-Type-Options
One value, one job: nosniff stops browsers from MIME-sniffing a response into an executable type. There is no tuning here — it is either present or a gap.
Referrer-Policy
Controls how much of your URL leaks to third parties in the Referer header. strict-origin-when-cross-origin is a safe default that keeps analytics working while stripping paths and query strings on cross-site requests.
Permissions-Policy Formerly Feature-Policy; disables browser APIs you don't use (camera, microphone, geolocation), shrinking the attack surface for compromised third-party scripts.
- Example:
Permissions-Policy: geolocation=(), microphone=(), camera=()
A note on X-XSS-Protection: it is deprecated in modern browsers, and current guidance is to send X-XSS-Protection: 0 (disabled) and rely on CSP instead — the opposite of what older tutorials tell you.
How to prioritize the report you get Free checkers grade differently: securityheaders.com surfaces the six core response headers above and scores from A+ down to F (source: https://securityheaders.com/), while Mozilla's Observatory adds a numeric score and cross-checks TLS and cookie flags alongside the headers (source: https://developer.mozilla.org/en-US/observatory). My fix order for a real deployment:
- HSTS — enforce HTTPS first, since every other header is delivered over the same channel.
- CSP (report-only → enforce) — highest payoff, longest to tune.
- X-Content-Type-Options and frame protection — instant, zero-risk wins.
- Referrer-Policy and Permissions-Policy — polish, and where most scanners dock the last points.
How to Check Security Headers on Your Website (Tools & Methods)
A practical, repeatable method (not just "paste a URL")
Most guides tell you to run one scanner and read the letter grade. That's incomplete. Grading engines weight headers differently, so the same site can score differently across tools — don't chase a single letter, read the per-header breakdown instead. Mozilla's HTTP Observatory grades a site on a 0-to-100 point scale (a perfect run scores 100), then maps that to letter grades from A+ down to F (source: https://developer.mozilla.org/en-US/observatory). Treat that number as a starting point, then verify the raw headers yourself.
Step-by-step:
- Scan the exact final HTTPS URL. Web scanners read the response headers of the URL you enter after redirects resolve. A header set only on the HTTP→HTTPS redirect hop (common with HSTS) can be missed — always test the canonical
https://address. - Cross-check two engines. Run one grader plus one raw viewer so you separate policy scoring from what was actually sent.
- Bypass the CDN once. Cloudflare/Fastly and similar proxies often inject headers. If you only scan the public hostname, you may see protection your origin server never sets. Scan the origin (or a direct IP host header) to confirm the app itself is hardened.
- Test authenticated and API endpoints too. Homepages usually look fine; login pages, admin panels, and JSON API routes are where
Content-Security-PolicyandCache-Controlgaps actually bite. - Re-scan after every deploy, since one framework upgrade or reverse-proxy change silently drops headers.
Which tool for which job:
- securityheaders.com — fastest single-URL grade with an A+ to F scale; best for a quick baseline (source: https://securityheaders.com/).
- Mozilla HTTP Observatory — most opinionated scoring, good for tracking improvement over time against its 0-to-100 scale (source: https://developer.mozilla.org/en-US/observatory).
- headerscan.com / apivoid.com — clean raw-header dumps, useful for the "what was literally sent" verification step (sources: https://headerscan.com/ , https://www.apivoid.com/tools/security-headers/).
- serpworx.com / sitesecurityscore.com — free checkers handy for a second opinion when a grader and a raw viewer disagree (sources: https://www.serpworx.com/check-security-headers/ , https://www.sitesecurityscore.com/free-security-headers-checker).
Confirm from the command line (no tool can hide this):
curl -sI https://yourdomain.com
Read strict-transport-security, content-security-policy, x-content-type-options, referrer-policy, and permissions-policy directly. If the CLI shows a header but a web scanner doesn't, you've likely hit a CDN or redirect difference — investigate before trusting the grade.
Common Security Header Misconfigurations and Risks
Why "green" grades lie. Most header checkers reward presence, not correctness. A header can exist, satisfy the scanner, and still protect nothing. These are the misconfigurations that pass a quick scan yet leave exploitable gaps:
-
HSTS with a too-short
max-age. Teams often shipStrict-Transport-Securitywith a tinymax-agejust to make the header show up. Mozilla Observatory only credits HSTS whenmax-ageis at least 15768000 seconds — six months (source: https://developer.mozilla.org/en-US/observatory); anything shorter leaves a downgrade window on first visit. DroppingincludeSubDomainsis the same trap: one forgotten subdomain served over HTTP can still set or read cookies. -
CSP that keeps
'unsafe-inline'or a*source. AContent-Security-Policycontaining'unsafe-inline'inscript-srcneutralizes its core XSS defense while the header still reads as "present." Grade-by-existence tools mark it as done; only policy-aware inspection flags it. My rule for reviews: treat any CSP with'unsafe-inline',data:inscript-src, or a wildcard host as not implemented, regardless of the letter grade. -
Over-counting on a "6-header" scorecard. securityheaders.com builds its A+ to F grade around 6 core response headers (source: https://securityheaders.com/):
Strict-Transport-Security,Content-Security-Policy,X-Frame-Options,X-Content-Type-Options,Referrer-Policy,Permissions-Policy. Because the grade is largely additive, a site with a broken CSP but five other headers set can still land an A — so read the per-header detail, not the badge. -
Leaning on
X-XSS-Protection. It is deprecated, ignored by modern browsers, and can even introduce filter-based bugs. Scanners now warn on it instead of rewarding it; do not use it to "pad" a score. -
Missing
X-Content-Type-Options/X-Frame-Options. Absentnosniffallows MIME-sniffing of user uploads into executable types; absent frame protection (or CSPframe-ancestors) leaves the page open to clickjacking. -
Referrer and Permissions leakage. No
Referrer-Policycan send full URLs (tokens, IDs in query strings) to third parties; noPermissions-Policyleaves camera, mic, and geolocation enabled by default for embedded content.
Practical takeaway: run the header URL through two graders and reconcile them — a presence-based tool for coverage and a policy-aware one for CSP quality — then re-verify the two settings that scanners most often "pass" on a technicality: the HSTS max-age value and the CSP source list.
Best Practices for Implementing Security Headers
Treat security headers as code, not a one-time checkbox. The practices below focus on rollout mechanics and validation that most checklists skip.
1. Cross-validate, because a single grade lies. No two scanners weight headers the same way, so a passing result in one tool can hide gaps in another. Run every change through at least 2 independent scanners: Mozilla's HTTP Observatory rates each scan on a 0–100 point scale before assigning a letter grade (source: https://developer.mozilla.org/en-US/observatory), while securityheaders.com returns a single letter grade from A+ down to F (source: https://securityheaders.com/). If the two disagree, the header is misconfigured, not the tool.
2. Stage the two "breaking" headers with a report-only phase. Content-Security-Policy and Strict-Transport-Security cause the most outages. My rollout order:
- Ship
Content-Security-Policy-Report-Onlyfirst, collect violation reports, then flip to the enforcing header once the report stream is clean. - Set HSTS with a short
max-agefirst, verify no mixed-content or subdomain breakage, then raise it and addpreloadlast — becausepreloadis effectively irreversible for months. - Never enable
preloadbefore the report-only checks pass; a bad preload entry locks users out until browser lists refresh.
3. Prioritize headers by blast radius, not alphabet. Deploy in this sequence so the highest-impact protections land first:
- Strict-Transport-Security (transport)
- Content-Security-Policy (injection/XSS)
- X-Content-Type-Options: nosniff (MIME confusion)
- X-Frame-Options / frame-ancestors (clickjacking)
- Referrer-Policy and Permissions-Policy (data leakage, feature abuse)
4. Automate the check in CI, not after deploy. Add a scanner call to your pipeline and fail the build if the grade drops. The free checkers each return results in well under a minute (for example, https://www.sitesecurityscore.com/free-security-headers-checker and https://www.apivoid.com/tools/security-headers/), so a per-deploy scan costs seconds, not human review time.
5. Scan every hostname, not just the apex. Headers set on www often miss api., cdn., and staging subdomains. Re-run https://headerscan.com/ against each public host, since a missing nosniff on an asset domain still enables MIME-based attacks even when the main site scores an A.
6. Re-scan on a schedule to catch drift. Reverse proxies, CDNs, and framework upgrades silently strip or override headers. Bookmark a fixed report URL (for example https://www.serpworx.com/check-security-headers/) and re-verify after any infrastructure change, not just after code changes.
How ZeroThreat Helps Automate Security Header Checks
Manual checkers are great for a one-off look, but they don't scale. Tools like securityheaders.com grade a single response against a core set of six headers—Strict-Transport-Security, Content-Security-Policy, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, and Permissions-Policy—returning a letter grade from A+ to F for that one URL (source: https://securityheaders.com/). Mozilla's tool goes further, scoring a page on a 0–100 scale and deducting points per missing or misconfigured header, but again for one hostname per run (source: https://developer.mozilla.org/en-US/observatory). ZeroThreat is built for the gap those tools leave: repeated, cross-URL, in-pipeline verification.
Here is where automation changes the workflow:
- Whole-site coverage, not one URL. Instead of pasting URLs one at a time into a free checker, ZeroThreat crawls every discovered endpoint and evaluates header posture per route, so a strong homepage doesn't hide a weak
/apior/login. - CI/CD gating. A build can fail automatically when a deploy reintroduces a missing HSTS or a loosened CSP—something a manual visit to a checker will never catch on time.
- Drift detection over time. Header configs regress silently after framework upgrades; scheduled scans flag the exact release where a header disappeared.
- Correlated findings. Header gaps are reported alongside the actual attack they enable (clickjacking, MIME sniffing, mixed content), not as an isolated grade.
A practical way to combine both: keep a free tool as a quick sanity spot-check, then use ZeroThreat as the enforcement layer. My recommended cadence:
- Run a manual scan on securityheaders.com or Mozilla's observatory once when shipping a new public page.
- Register that page in ZeroThreat for continuous, authenticated scanning.
- Set the pipeline threshold to reject any regression before it reaches production.
The difference is scope: a free checker tells you the score of one page today; automated scanning keeps every page above that score on every deploy.
