HTTP Security Headers: The Complete Checklist
Published
HTTP security headers are instructions your web server sends in every response that tell the browser how to behave defensively: force encryption, block framing, restrict which scripts can run, and stop data leaking to third parties. They are free, they take minutes to deploy, and most of the web still skips them. The August 2026 defaults.exposed census scored every major security header across 432,127,908 scanned domains and found a consistent pattern of neglect — only 8.0% set a Content-Security-Policy, just 20.1% deploy HSTS, 91% omit Referrer-Policy entirely, and cross-origin isolation headers cover under 1% of sites. This is the complete checklist: the six headers that matter, what each one stops, how to add them on nginx, Apache, Caddy, and Cloudflare, and how to check your own domain in 30 seconds.
A security header costs nothing and breaks nothing when it is configured correctly, yet the census shows the modern web treats the whole category as optional. The gap is not technical difficulty — every header below is a single line of server configuration — it is that most site owners have never seen their own header posture stated plainly. The figures throughout come from the defaults.exposed August 2026 census, an independent scan of 432,127,908 domains graded as of 2026-08-16.
What are HTTP security headers?
HTTP security headers are extra fields a web server adds to the response it sends the browser, alongside the page itself. They carry no visible content. Instead, each one is a policy the browser agrees to enforce on the site’s behalf — a set of guardrails that turn the browser from a passive renderer into an active participant in the site’s defence.
A normal response already carries headers: Content-Type, Content-Length, Set-Cookie, and so on. Security headers are the subset whose only job is to constrain behaviour. Strict-Transport-Security tells the browser never to load the site over plain HTTP again. Content-Security-Policy tells it which scripts, styles, and images it is permitted to load and execute. X-Frame-Options tells it whether the page may be embedded in a frame. Each is a short string; each closes a specific class of attack.
The important properties are three. First, they are server-controlled — the site owner sets them, not the visitor, so they cannot be disabled by the attacker who is trying to abuse the page. Second, they are enforced by the browser, which means they protect the user even when the user does nothing. Third, they are publicly visible: anyone can fetch your homepage and read exactly which headers you send, which is precisely how the census measured them, and how an attacker assesses whether your site is worth targeting. For the full grading logic behind each header, see the defaults.exposed methodology index.
Security headers are a layer, not the whole wall. They do not replace input validation, patched software, or a well-configured server — they are the browser-side layer of a defence-in-depth model, catching the attacks that only the browser is positioned to stop. An injected script, a hostile frame, a downgraded connection, a leaked referrer: these all play out inside the visitor’s browser, which is why the instruction to stop them has to travel there. That is the gap headers fill, and nothing on the server can fill it for them. It also explains why they are worth setting even on a site you believe is otherwise secure: they are the last line, active precisely when an earlier control has already failed.
The essential security headers checklist (the six that matter)
Dozens of response headers exist. Six carry the overwhelming majority of the security value, and a site that sets all six correctly has closed the common browser-side attack surface. Here is each one, what it does, and the value to aim for.
1. Strict-Transport-Security (HSTS). Forces the browser to use HTTPS for every future request to your domain, even if a user types http:// or clicks an old link. It closes the downgrade window that lets an on-path attacker strip encryption. Aim for max-age=31536000; includeSubDomains; preload. The census found HSTS on just 20.1% of the responding web (46,539,716 domains), and only 2.57% are preload-ready. The full picture is in What is HSTS: the header 79.9% of sites still skip and the HSTS methodology.
2. Content-Security-Policy (CSP). The most powerful and most under-used header. It declares which sources the browser may load scripts, styles, frames, and other resources from, which shrinks or eliminates cross-site scripting (XSS) and injection. A strict starting point is default-src 'self'. Only 8.0% of the web sets any CSP at all — detailed in Content-Security-Policy adoption in 2026: the 8.0% web and the CSP methodology.
3. X-Frame-Options. Stops other sites embedding your pages inside an invisible frame to trick users into clicking things they cannot see — clickjacking. Set it to DENY (or SAMEORIGIN if you frame your own pages). Modern practice layers CSP frame-ancestors on top. The attack and its defences are covered in What is clickjacking, X-Frame-Options, and how to stop it and the X-Frame-Options methodology.
4. X-Content-Type-Options: nosniff. A one-value header that tells the browser to trust the declared Content-Type and never guess. Without it, a browser may “sniff” a file’s contents and execute an uploaded image or text file as script. There is exactly one correct value — nosniff — and no reason to omit it. See the X-Content-Type-Options methodology.
5. Referrer-Policy. Controls how much of the current URL the browser reveals to sites you link to or load resources from. Left unset, the browser can leak full URLs — including path segments that contain session tokens, reset links, or internal identifiers — to third parties. A safe default is strict-origin-when-cross-origin. The census found 91% of sites omit this header entirely; the privacy cost is quantified in Referrer-Policy: the privacy header 91% of the web forgot and the Referrer-Policy methodology.
6. The cross-origin isolation headers (COOP, COEP, CORP). The advanced tier. Cross-Origin-Opener-Policy, Cross-Origin-Embedder-Policy, and Cross-Origin-Resource-Policy together isolate your page from a family of cross-origin side-channel and cross-site-leak attacks, and they gate access to high-precision browser features. Fewer than 1% of sites deploy them, as measured in The isolation headers: why COOP, COEP and CORP cover less than 1% of the web and the COOP methodology. Most sites do not strictly need full isolation, but the near-total absence signals how few operators reach the frontier of header hardening.
Beyond these six sits Permissions-Policy, which switches off browser features (camera, geolocation, microphone) a site does not use. It is worth adding, but the six above carry the core defensive weight and are the ones the census grades directly.
The census scoreboard: how many sites actually set each
Reading the whole internet’s response headers produces a scoreboard of neglect. Every figure below is the share of the responding web that sets the header at all — before any question of whether the value is strong.
| Security header | What it protects | Adoption (Aug 2026 census) |
|---|---|---|
| Strict-Transport-Security (HSTS) | Forces HTTPS, blocks downgrade | 20.1% — 46,539,716 domains |
| Content-Security-Policy (CSP) | Restricts scripts and resource loading | 8.0% |
| Referrer-Policy | Limits URL leakage to third parties | ~9% (91% omit it) |
| Isolation trio (COOP / COEP / CORP) | Isolates the page cross-origin | under 1% |
The census also grades X-Frame-Options and X-Content-Type-Options as part of the header suite; X-Frame-Options adoption and the shift toward CSP frame-ancestors are covered in the clickjacking report.
Two patterns stand out. First, adoption falls sharply as headers get more powerful: the more a header actually constrains an attacker, the less often it is set. HSTS, which is close to zero-risk to deploy, still reaches only one site in five. CSP, the single most effective control against XSS, reaches fewer than one in twelve. Isolation, the strongest tier, is statistical background noise.
Second, headers cluster. A domain that sets one strong header tends to set others, and a domain that sets none tends to set none — security posture is bimodal, not evenly spread. The correlation structure across the whole control set is analysed in The security correlation: which controls cluster together and which sit alone. The practical reading is encouraging: the headers travel together, so an operator who commits to a header baseline usually fixes the whole set in one configuration change rather than one header at a time.
Check your domain free at defaults.exposed — it fetches your live response headers and grades every one of the six against these census benchmarks, so you can see exactly where you sit on the scoreboard in about 30 seconds.
Which headers stop which attacks (a mapping)
A checklist is easier to act on when each item is tied to the concrete threat it removes. Headers are not interchangeable — each closes a distinct door, which is why the goal is coverage of the set rather than picking a favourite.
| Attack class | The header that closes it | How it works |
|---|---|---|
| SSL stripping / protocol downgrade | Strict-Transport-Security | Browser refuses plain HTTP for the domain, so an on-path attacker cannot force an unencrypted connection |
| Cross-site scripting (XSS) / injection | Content-Security-Policy | Browser only executes scripts from sources the policy allows, so injected inline script does not run |
| Clickjacking / UI redress | X-Frame-Options and CSP frame-ancestors | Browser refuses to render the page inside a hostile frame |
| MIME confusion / content sniffing | X-Content-Type-Options: nosniff | Browser trusts the declared type and will not execute a mislabelled file as script |
| URL / token leakage | Referrer-Policy | Browser withholds sensitive path and query data from third-party destinations |
| Cross-origin side-channel / XS-leaks | COOP / COEP / CORP | Browser isolates the document so cross-origin pages cannot probe or steal from it |
The mapping shows why “we have HTTPS” is not the same as “we are secure.” HTTPS encrypts the connection; it does nothing about a script injected into your own page, a frame wrapped around it, or a URL leaking out of it. Each of those is a separate header’s job, and encryption is the precondition — not a substitute — for the rest. This is also why the six work as a set: an attacker only needs one open door, so a site that sets five of six is defended against five attack classes and exposed to the sixth.
How to add security headers (nginx, Apache, Cloudflare, Caddy)
Adding the core headers is a few lines of configuration on any common stack. The values below are a safe, strict baseline; tighten CSP once you have inventoried the resources your pages legitimately load.
nginx — inside the server block. The always flag is important, so the headers are also sent on error responses, not just 200 OK:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header Content-Security-Policy "default-src 'self'" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Apache — in the virtual host or .htaccess, with mod_headers enabled. always places the header in the correct output table so it applies to error pages too:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header always set Content-Security-Policy "default-src 'self'"
Header always set X-Frame-Options "DENY"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Caddy — inside the site block; Caddy serves HTTPS by default, which is half the battle already:
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Content-Security-Policy "default-src 'self'"
X-Frame-Options "DENY"
X-Content-Type-Options "nosniff"
Referrer-Policy "strict-origin-when-cross-origin"
}
Cloudflare — add headers at the edge without touching the origin, using Rules → Transform Rules → Modify Response Header, or enable HSTS directly under SSL/TLS → Edge Certificates. This matters at scale: the census found 41.9 million domains fronted by Cloudflare, every one of which can gain the full header set from a single dashboard change that never touches the web server behind it.
Two rules apply on every stack. Send the headers on all responses, including redirects and error pages, or an attacker simply targets the unprotected path. And roll CSP out in stages — start with Content-Security-Policy-Report-Only to observe what would break before you enforce, exactly as you would stage an email-authentication policy before turning it on.
Legacy headers to drop (a complete checklist removes, too)
A genuinely complete header checklist is not only about what to add. Several headers that were once recommended are now deprecated, ignored by modern browsers, or actively harmful, and they still linger in copied-and-pasted configurations across the web. Removing them is part of the same maintenance pass.
X-XSS-Protection. This toggled the legacy XSS auditor built into older browsers. Modern browsers have removed the feature entirely, and in some past configurations the auditor could itself be abused to leak data. The current guidance is to set it to0or simply delete it;Content-Security-Policyis its proper replacement.Public-Key-Pins(HPKP). Certificate pinning by header is deprecated and dropped from browsers. It was removed precisely because a misconfiguration — or an attacker who managed to set a pin — could render a domain unreachable for the pinned lifetime. Never deploy it.Expect-CT. This enforced Certificate Transparency reporting during the transition years. Certificate Transparency is now required by default for publicly trusted certificates, which makes the header obsolete. It is safe to remove.- Version banners (
Server,X-Powered-By,X-AspNet-Version). These are not security headers, but they hand an attacker your exact software and version, which is the first thing an automated scanner uses to match a known exploit. Trimming them to a generic value costs nothing. The scale of the exposure they advertise is measured in the end-of-life software census: 6.6 million servers admit it.
The rule of thumb: if a header no longer changes browser behaviour, it is noise; if it can only reduce availability or reveal your stack, it is a liability. Both belong on the removal list, not the checklist.
How to check your headers and spot common misconfigurations
You can read your own headers in three ways, from quickest to most thorough.
- Browser DevTools. Open the Network tab, reload the page, click the top request, and read the Response Headers panel. It shows precisely what a visitor’s browser received.
- The command line.
curl -sI https://yourdomain.comprints every response header in one line each — the fastest way to diff two environments or confirm a deploy. - A free scanner. A grader fetches your live headers, checks each value against best practice, and flags the gaps in one report — no account, no install.
Reading the headers is only half the job; the values have to be right. The census and everyday audits turn up the same handful of misconfigurations again and again:
- HSTS with a tiny
max-ageor noincludeSubDomains. Amax-ageof a few minutes, or one that excludes subdomains, leaves most of the downgrade window open. Aim for a full year and include subdomains before considering preload. - CSP that allows
unsafe-inlineorunsafe-eval. These directives re-open the exact hole CSP exists to close. A policy full ofunsafe-*is present in the census but provides little real protection. - Report-Only CSP left in monitoring mode forever.
Content-Security-Policy-Report-Onlyobserves but never blocks — the browser-header equivalent of a DMARC policy stuck atp=none. It is the correct first step and the wrong permanent state. - Headers on the homepage but not everywhere. Headers set on HTML pages but missing from API responses, error pages, or redirects leave the unprotected paths exploitable. Set them globally at the server or edge, not per-route.
- Duplicate or conflicting headers. Two
X-Frame-Optionsvalues, or a header set at both the origin and the CDN, can produce undefined behaviour. One authoritative source per header.
Check your domain free at defaults.exposed — it reads your live response headers straight from the wire, grades each of the six against best practice, and shows you which are missing, which are weak, and which are set correctly. If you want the gaps closed properly across your whole estate, see how the fix works.
What this means
For business owners, the header scoreboard is a plain readout of risk that costs nothing to close. Missing HSTS means a customer on public Wi-Fi can be silently downgraded to an unencrypted connection. A missing CSP means an injected script can run on your checkout page. A missing Referrer-Policy can leak a password-reset URL to an advertising network. None of these require a budget or a project — each is a line of configuration your host or developer can add in an afternoon. At the census rates of 8.0% for CSP and 20.1% for HSTS, doing the basics puts you ahead of most of the web.
For IT and security teams, the six headers are a baseline you can standardise and enforce once, at the edge or in a shared server template, then verify continuously. Because the headers cluster, a single well-configured baseline usually fixes the whole set rather than one control at a time. Treat CSP as the multi-week project it is — inventory your resources, stage in Report-Only, then enforce — and treat the other five as same-day wins. Bake the baseline into your reverse proxy or CDN so new services inherit it by default rather than re-deriving it, and add a header check to your deploy pipeline so a regression fails the build instead of shipping silently. The measurable goal is simple: every response, on every path, carrying all six.
FAQ
What are HTTP security headers? HTTP security headers are fields a web server includes in its responses that instruct the browser to enforce specific protections — forcing HTTPS, restricting which scripts may run, blocking the page from being framed, and limiting what data leaks to third parties. They carry no visible page content; each is a short policy string the browser obeys on the site’s behalf. Because they are server-set and browser-enforced, they protect visitors automatically. They are also publicly visible, which is how the August 2026 census could grade them across 432,127,908 scanned domains and find most sites setting few or none.
Which security headers are most important?
Six carry the bulk of the value. Strict-Transport-Security (HSTS) forces HTTPS; Content-Security-Policy (CSP) blocks cross-site scripting; X-Frame-Options stops clickjacking; X-Content-Type-Options: nosniff prevents MIME-sniffing; Referrer-Policy limits URL leakage; and the isolation trio (COOP/COEP/CORP) defends against cross-origin side-channels. If you deploy only two, make them HSTS and CSP — the census found HSTS on 20.1% of sites and CSP on just 8.0%, so both are high-impact and widely skipped. A site setting all six has closed the common browser-side attack surface.
How do I add security headers to my website?
Add them in your web server or CDN configuration — a few lines, applied to every response. On nginx use add_header ... always;; on Apache use Header always set ...; on Caddy use a header { } block; on Cloudflare use Transform Rules or the SSL/TLS edge settings. A safe baseline is default-src 'self' for CSP, DENY for X-Frame-Options, nosniff for X-Content-Type-Options, strict-origin-when-cross-origin for Referrer-Policy, and max-age=31536000; includeSubDomains for HSTS. Roll CSP out in Report-Only mode first so you can see what would break before you enforce it.
How do I check my website’s security headers?
Three ways, quickest first: open your browser’s DevTools Network tab and read the Response Headers panel; run curl -sI https://yourdomain.com to print every header; or use a free scanner that grades each header for you. Check your domain free at defaults.exposed — it fetches your live headers, checks each of the six against best practice, and flags what is missing, weak, or correct in about 30 seconds, no account required. Re-check after any deploy, because headers set on the homepage but dropped on error pages or API routes are a common and exploitable gap.
Data to cite
- “Content-Security-Policy is set by only 8.0% of the web, leaving the single most effective defence against cross-site scripting absent from more than nine sites in ten.” — defaults.exposed August 2026 Domain Security Census (432M domains)
- “HSTS is deployed by just 20.1% of the responding web — 46,539,716 domains — meaning 79.9% ship no protection against protocol downgrade.” — defaults.exposed August 2026 Domain Security Census (432M domains)
- “Referrer-Policy is omitted by 91% of sites, leaving full URLs — including tokens embedded in paths — free to leak to third-party destinations.” — defaults.exposed August 2026 Domain Security Census (432M domains)
- “Cross-origin isolation headers (COOP, COEP and CORP) sit under 1% adoption, making the strongest tier of browser hardening effectively absent from the web.” — defaults.exposed August 2026 Domain Security Census (432M domains)
- “These security headers were scored across all 432,127,908 domains scanned in the August 2026 census, an independent measurement of the public web.” — defaults.exposed August 2026 Domain Security Census (432M domains)
See where your own domain stands
A security-header checklist is only useful once you know which lines your own site is missing. Most operators have never looked, which is exactly why the census reads the way it does — 8.0% for CSP, 20.1% for HSTS, 91% with no Referrer-Policy at all. The scoreboard is not a verdict on hard problems; it is a record of headers that were never added.
Check your domain free at defaults.exposed — it reads your live response headers, grades every one of the six against best practice, and tells you instantly which are missing, which are weak, and which are set correctly. Takes 30 seconds. No account needed. If you want the whole set deployed and kept right across your estate, see how the fix works.
Read the flagship census report: The State of Domain Security 2026 →
Related from this series: What is HSTS: the header 79.9% of sites still skip · Content-Security-Policy adoption in 2026: the 8.0% web · What is clickjacking, X-Frame-Options, and how to stop it · Referrer-Policy: the privacy header 91% of the web forgot · The isolation headers: COOP, COEP and CORP under 1%
Aggregate data only. Data stored and processed in the EU.
Data source: defaults.exposed August 2026 census, methodology v9, as of 2026-08-16. 432,127,908 domains scanned; security headers graded on the responding web. All figures are aggregate distributions. References: RFC 6797 (HSTS), CSP Level 3, RFC 9110 (HTTP Semantics).
How to cite this report
Press / blog: defaults.exposed (2026). HTTP Security Headers: The Complete Checklist. defaults.exposed August 2026 Domain Security Census (432,127,908 domains scanned, asOf 2026-08-16). Retrieved from https://defaults.exposed/v9/articles/http-security-headers-the-complete-checklist
Academic: defaults.exposed. (2026, August 21). HTTP Security Headers: The Complete Checklist. In defaults.exposed Domain Security Census: August 2026. https://defaults.exposed/v9/articles/http-security-headers-the-complete-checklist
In-line citation: (defaults.exposed, August 2026 Domain Security Census, n=432,127,908 scanned domains)
About the defaults.exposed August 2026 Census
The defaults.exposed Domain Security Census is a recurring independent measurement of the public domain namespace. The August 2026 edition scanned 432,127,908 domains between 1–16 August 2026 and graded them using methodology v9. Scans are conducted from EU infrastructure. No individual domain, registrant, or business is named in any report. All figures are aggregate distributions. Data is stored and processed within the EU.
Methodology: defaults.exposed/v9/methodology Full census report: defaults.exposed/en/articles/the-state-of-domain-security-2026
Data sourced from the August 2026 grading methodology (v9) — 34 checks, 376 million domains. Browse the census statistics or the Census Explorer, or see all August 2026 research →