Security headers on the top 1,000 websites: 677 homepages checked
On 9 November 2026 we sent one GET request to the homepage of each of the top 1,000 domains in Tranco list 8P8NV. 677 answered. Half pass the HSTS check, 46% send no Content-Security-Policy, 5.5% pass our CSP check, and 19% disclose a software name or version. The raw results are free to download.
We checked the security headers of the top 1,000 domains from the Tranco ranking on 9 November 2026. 677 of them returned a response we could grade. About half of those set HSTS with a max-age of one year or more, and 5.5% send a Content-Security-Policy that passes our check.
Method#
The list is Tranco list 8P8NV, the top 1,000,000, created 8 November 2026 from data for 10 October to 8 November 2026 (combination method: Dowdall; providers: Chrome UX Report, Farsight, Majestic, Cloudflare Radar and Umbrella). We took the first 1,000 entries by rank. Tranco filters the list to registrable domains, so many entries are infrastructure names such as CDNs and API hosts, not sites with a homepage.
For each domain we called the code behind our free security headers checker once with https://<domain>/. Up to 8 checks ran at the same time. The checker sends one GET request per redirect hop, up to 5 hops, with the user agent ExcessionLabsHeaderCheck/1.0, and reads response headers only. It never returns or stores a page body. We retried 90 domains once after a network error or a timeout. The run took place on 9 November 2026 from one machine.
The checker grades each response on 8 checks that we count in the pass totals: HTTPS, HSTS (max-age at least 31,536,000 seconds, one year), Content-Security-Policy, clickjacking protection, X-Content-Type-Options, Referrer-Policy, Permissions-Policy and version disclosure. It also records Cross-Origin-Opener-Policy, cookie flags, CORS and X-XSS-Protection, which we report separately. The rules follow the OWASP Secure Headers Project and MDN.
What the checker sees: the headers of the final response for the homepage address, after redirects. What it cannot see: other pages, logged-in pages, API hosts, what a browser would receive with cookies or a real browser's headers, anything a CDN changes by country or user agent, and whether a policy works as intended. A pass means the header is present and has no flagged weakness. It does not prove the policy is good.
What we got back#
| Outcome | Domains | Share of 1,000 |
|---|---|---|
| Response graded | 677 | 67.7% |
| No public address (DNS) | 217 | 21.7% |
| Points to a private or reserved address | 12 | 1.2% |
| No answer in 8 seconds | 50 | 5.0% |
| Could not be reached | 39 | 3.9% |
| More than 5 redirects | 2 | 0.2% |
| Refused by the checker's address rules | 3 | 0.3% |
Of the 677 graded responses, 540 were 2xx, 134 were 4xx and 3 were 5xx. Error pages often carry fewer headers than the real page, and some of the 4xx answers come from bot filters, so we also give the 2xx-only figures below. 147 of the 677 ended on a different host than the one we asked for, most often a www. name. 3 ended on plain http.
Results#
Percentages in this table use the 677 graded responses as the denominator. The last column uses only the 540 responses with a 2xx status.
| Check | Pass | Share of 677 | Share of 540 (2xx only) |
|---|---|---|---|
| HTTPS on the final page | 674 | 99.6% | 99.6% |
| Strict-Transport-Security | 338 | 49.9% | 55.4% |
| Content-Security-Policy | 37 | 5.5% | 6.7% (36) |
| Clickjacking protection | 347 | 51.3% | 53.3% |
| X-Content-Type-Options: nosniff | 371 | 54.8% | 57.0% |
| Referrer-Policy | 152 | 22.5% | 18.0% |
| Permissions-Policy | 147 | 21.7% | 19.6% |
| No version disclosure | 546 | 80.6% | 77.0% |
Across the 8 counted checks, the mean number of passes per graded site is 3.9. 2 sites passed all 8 and 34 passed 7.
| Checks passed (of 8) | Sites | Share of 677 |
|---|---|---|
| 1 | 35 | 5.2% |
| 2 | 136 | 20.1% |
| 3 | 140 | 20.7% |
| 4 | 122 | 18.0% |
| 5 | 105 | 15.5% |
| 6 | 103 | 15.2% |
| 7 | 34 | 5.0% |
| 8 | 2 | 0.3% |
HSTS#
674 graded responses ended on https, and the table uses those as its denominator.
| HSTS max-age | Sites | Share of 674 |
|---|---|---|
| No header | 240 | 35.6% |
| Zero or unreadable | 3 | 0.4% |
| Under 6 months | 72 | 10.7% |
| 6 months to under 1 year | 21 | 3.1% |
| 1 year or more | 338 | 50.1% |
| of which 2 years or more | 75 | 11.1% |
245 sites set includeSubDomains and 179 set preload.
Content-Security-Policy#
| CSP state | Sites | Share of 677 |
|---|---|---|
| No CSP header | 312 | 46.1% |
| Report-Only header only | 25 | 3.7% |
| Enforced policy | 340 | 50.2% |
| Enforced policy that passes our check | 37 | 5.5% |
Among the 340 enforced policies, our check flagged the following weaknesses. A policy can have more than one.
| Weakness in an enforced policy | Policies | Share of 340 |
|---|---|---|
unsafe-eval allowed for scripts |
146 | 42.9% |
No script-src or default-src |
133 | 39.1% |
No object-src and no default-src 'none' |
180 | 52.9% |
unsafe-inline in script-src with no nonce or hash |
99 | 29.1% |
| Wildcard or scheme source in script-src | 61 | 17.9% |
We did not test why each policy allows these sources.
Version disclosure and cookies#
131 of 677 responses (19.4%) carried a header that names software or a version: 63 a versioned Server, 65 an X-Powered-By and 6 an X-Generator. Some responses had more than one.
395 responses set at least one cookie on the homepage. Of those, 231 (58.5%) had a cookie without Secure or without an explicit SameSite, and 258 (65.3%) had a cookie without HttpOnly. The checker reads the first 20 cookies of a response and does not know which cookie is a session cookie, so HttpOnly gaps on analytics cookies are normal and are not counted as a failure.
Cross-Origin-Opener-Policy: same-origin was set on 90 responses (13.3%). X-XSS-Protection, which OWASP now suggests setting to 0 or dropping, appeared on 172.
The first 20 graded sites by rank#
Domains are in Tranco rank order, with the status we received and the number of the 8 checks passed. The table is a snapshot of one homepage response. It says nothing about how well a company runs its security, and some of these names are API or CDN hosts where a homepage has no purpose.
| Rank | Domain | HTTP status | Checks passed (of 8) |
|---|---|---|---|
| 1 | google.com | 200 | 3 |
| 2 | cloudflare.com | 200 | 7 |
| 4 | amazonaws.com | 200 | 5 |
| 5 | facebook.com | 200 | 5 |
| 6 | fbcdn.net | 200 | 5 |
| 8 | gstatic.com | 404 | 3 |
| 9 | googleapis.com | 404 | 3 |
| 10 | youtube.com | 200 | 6 |
| 11 | microsoft.com | 200 | 2 |
| 12 | apple.com | 200 | 5 |
| 14 | instagram.com | 200 | 6 |
| 16 | twitter.com | 200 | 7 |
| 17 | linkedin.com | 200 | 6 |
| 18 | azure.com | 200 | 3 |
| 19 | triplinkintl.com | 200 | 2 |
| 24 | googletagmanager.com | 404 | 2 |
| 25 | appsflyersdk.com | 403 | 2 |
| 27 | mail.ru | 200 | 5 |
| 29 | amazon.com | 200 | 6 |
| 31 | office.com | 200 | 6 |
Most common gaps and what to do#
CSP is the largest gap: 46.1% send none and only 5.5% pass. Start with a Report-Only policy, read the reports for a few weeks, then enforce a policy built on nonces or hashes for scripts, with object-src 'none' and frame-ancestors. MDN's CSP page covers the syntax.
HSTS is missing on 35.6% of https responses, and a further 13.8% set a max-age under one year. OWASP suggests max-age=31536000; includeSubDomains. Check that every subdomain serves https before you add includeSubDomains.
X-Content-Type-Options: nosniff is missing on 306 graded responses (45.2%). It is one line and has little risk on a site that sends correct content types.
Version disclosure affects 19.4%. Remove X-Powered-By and X-Generator, and drop the version from Server. Hiding a version does not fix an old component, but it stops a scanner from reading your patch level off every response.
Cookies need Secure and an explicit SameSite, and session cookies need HttpOnly. A pentest checks whether these settings hold on the pages that matter, which a homepage check cannot do.
Monthly reruns#
We rerun the study each month with a scheduled job. Every run checks the same 1,000 domains, Tranco list 8P8NV ranks 1 to 1,000, so the runs compare. We do not move to a newer Tranco list, so domains that leave the current top 1,000 stay in the study. The checker rules stay the same, and timeouts and network errors get one retry, as in the first run. The first run, on 9 November 2026, is the baseline, and the figures in the sections above come from it.
Reruns send their requests from Cloudflare's network, not from the single machine of the first run. Some sites answer the two in different ways, so part of a change can come from where the requests start.
| Run | Domains graded (of 1,000) | HSTS pass | CSP pass | No CSP header | nosniff pass | Clickjacking pass | Mean checks passed (of 8) |
|---|---|---|---|---|---|---|---|
| 9 November 2026 (baseline) | 677 | 49.9% | 5.5% | 46.1% | 54.8% | 51.3% | 3.9 |
Every run checks the same 1,000 domains (Tranco list 8P8NV, ranks 1 to 1,000) with the same checker rules, so the rows compare. Percentages use the graded responses of each run. The first run, on 9 November 2026, is the baseline for every figure on this page. The study reruns each month, and each run adds one row to this table. The per-domain results of the latest run are in latest.csv.
Limitations#
- Each run sends one request per domain. The baseline came from one machine on one day. Bot filters, regional answers and rate limits can change the headers a site returns.
- Homepage only. Login, checkout and API hosts often set different headers.
- 323 of 1,000 domains gave no graded result, and they are mostly not websites. The results describe the 677 that answered, not the Tranco top 1,000 as a whole.
- 134 of the graded responses were 4xx answers. We report the 2xx-only figures beside the full ones.
- Pass and fail follow our checker's rules. Another tool with other thresholds will give other numbers. For example, our CSP check flags
unsafe-inlineonly when no nonce or hash is present. - Headers are a hardening layer. This study does not test applications, and a site with every header set can still have broken access control.
Download the data#
- results.csv: the baseline run, one row per domain, with rank, final URL, HTTP status, the status of each check and the error for failed fetches.
/research-data/security-headers-top-1000/results.jsonl(JSON Lines, 2 MB): the full checker output per domain, including header values and the redirect hops.- summary.json: every baseline figure on this page with its denominator.
- latest.csv: the latest finished monthly run, in the same columns as results.csv. Until the first rerun finishes, it is the baseline file.
To check your own site, use the security headers checker. Headers are one part of a web app test. See web application penetration testing for what else a test covers.
Questions
Does a missing header mean a site is vulnerable?
No. A header limits the damage when another bug exists, such as cross-site scripting or a downgrade to http. A site can lack a header and have no exploitable flaw. This study counts headers on one response and tests nothing else.
Why did 323 of the 1,000 domains fail to produce a result?
Most are domains that serve no website at the bare name. 217 have no public address and 12 point to a private or reserved address. Another 89 did not answer in 8 seconds or could not be reached, 2 redirected more than 5 times, and 3 were refused by the checker's address rules. Failed fetches are left out of every percentage.
Can I rerun the study?
Yes. Tranco list 8P8NV is permanent, and the checker is free. Headers change, so a rerun will not match exactly. The results file lists the final URL and every check status for each domain.
How do I check my own site?
Open the free security headers checker, enter your address, and read the value and the note for each check. It sends one GET request per redirect and reads headers only.
Sources
- Tranco list 8P8NV, top 1,000,000, created 8 November 2026 (checked 9 November 2026)
- OWASP Secure Headers Project (checked 9 November 2026)
- MDN: Content-Security-Policy header (checked 9 November 2026)