Free checker · 3 checks a day, more with a free account
Security Headers Checker
Find out which security headers your site sends, which ones the browser actually enforces, and exactly how to fix the rest.
Only test sites you own or are authorised to test.
Security headers tell the browser how to protect your visitors: which scripts may run (Content-Security-Policy), to always use HTTPS (Strict-Transport-Security), who may frame the page, what a cookie may be used for. A header that is present but misconfigured protects nothing, so this checker reads every value the way a browser does and shows you the bytes behind each finding.
What it checks.
Graded by what the browser enforces
A header the browser ignores scores as absent: HSTS over HTTP or with max-age=0, X-Frame-Options ALLOW-FROM, a CSP only in Report-Only, frame-ancestors in a <meta> tag, Permissions-Policy in the old Feature-Policy syntax.
Two numbers, one letter
Coverage says which protections are deployed; effectiveness says how much they protect. The letter follows the lower one, so a CSP full of 'unsafe-inline' cannot hide behind an A.
CSP, directive by directive
Google's CSP Evaluator checks plus the strict-CSP level (nonce, hash, 'strict-dynamic'), meta-tag limits, multiple policies, known bypass hosts and the reporting wiring.
HSTS, redirects and cookies
max-age, includeSubDomains and preload rules; HTTP to HTTPS on the same host with HSTS on the redirect; every cookie's Secure, HttpOnly, SameSite and prefix rules.
Fixes for your platform
Every finding has a copy-ready snippet for Nginx, Apache, Cloudflare, Netlify, Vercel, Next.js and WordPress, plus one block that applies every missing header at once.
Honest about firewalls
If Cloudflare, Sucuri, Imperva, Akamai, AWS WAF or Wordfence challenges our scanner, we say so (with the Ray ID) instead of handing you a false F.
Raw headers as received
Every hop of the redirect chain with header names in their original casing and order, duplicates kept, captured from outside Cloudflare by our own probe.
Share, API, watch
A share link for every result, a keyless JSON API, and a Watch button that adds the site to your monitored assets.
Methodology.
Grade v1.1. We fetch the URL from our probe (US East), follow redirects one by one, and grade the final response. For an https address we also fetch http://<host>/ to check the redirect to HTTPS. Two scores, each 0 to 100; the letter comes from the lower one. Items that do not apply (no cookies, no Referrer-Policy header, an API response) are left out of coverage rather than counted against you.
Coverage: what is deployed and effective
| Protection | Max | Rule |
|---|---|---|
| Content-Security-Policy (enforced) | 25 | 10 for any enforced policy; 15 when scripts are restricted (no effective 'unsafe-inline', no wildcard or scheme-only sources); 20 / 23 / 25 for the strict levels L1 / L2 / L3 (nonce or hash with 'strict-dynamic' and 'unsafe-eval' / without 'unsafe-eval' / nonce- or hash-only) |
| Strict-Transport-Security | 15 | 15 for max-age of a year or more with includeSubDomains; 12 for a year without; 10 for six months to a year; 5 for less; 0 when ignored (HTTP, max-age=0, invalid certificate) |
| Framing control | 10 | CSP frame-ancestors (header, not meta) or X-Frame-Options DENY / SAMEORIGIN; ALLOW-FROM counts as absent |
| X-Content-Type-Options | 5 | exactly nosniff |
| Referrer-Policy | 5 | a private value (no-referrer, same-origin, strict-origin, strict-origin-when-cross-origin); the last valid token counts; not counted when the header is absent or has no valid value, because the browser then applies strict-origin-when-cross-origin by itself |
| Permissions-Policy | 5 | a policy that parses as a structured header; N/A for API responses |
| Cookies | 15 | share of cookies with every applicable flag (Secure; HttpOnly for session cookies; SameSite; valid prefixes); N/A when no cookie is set |
| Cross-Origin-Opener-Policy | 5 | same-origin, same-origin-allow-popups or noopener-allow-popups; N/A for API responses |
| Cross-Origin-Resource-Policy | 5 | same-origin, same-site or cross-origin |
Effectiveness: 100 minus deductions
| CSP-UNSAFE-EVAL | CSP allows 'unsafe-eval' (not charged on a strict policy at level L1, whose 20 points instead of 23 are that charge) | −10 |
| CSP-KNOWN-BYPASS-HOST | An enforced CSP allowlists a host with a known bypass (JSONP, AngularJS, Flash) | −10 |
| CSP-MISSING-OBJECT-SRC | CSP has neither object-src nor default-src | −5 |
| CSP-MISSING-BASE-URI | CSP uses nonces or hashes without base-uri | −5 |
| CSP-LEGACY-HEADER-NAME | A pre-standard CSP header name is sent (X-Content-Security-Policy, X-WebKit-CSP) | −2 |
| HSTS-NO-INCLUDESUBDOMAINS | HSTS without includeSubDomains, when max-age is under a year (with a year or more the coverage points say so: 12, not 15) | −5 |
| HSTS-PRELOAD-NOT-ELIGIBLE | HSTS preload directive without the preload requirements | −5 |
| REDIRECT-MISSING | HTTP does not redirect to HTTPS | −10 |
| REDIRECT-OFF-HOST-FIRST-HOP | The first redirect from HTTP leaves the host (HSTS never set for it) | −5 |
| COOKIE-* | Cookie exposures (session cookie without Secure 20, without HttpOnly 15, SameSite=None without Secure 10; capped at 30). Other flag gaps count through the coverage share only | −30 |
| CORS-WILDCARD-WITH-CREDENTIALS | Access-Control-Allow-Origin * with credentials | −20 |
| DEPRECATED-* | Deprecated or harmful headers present (2 each, capped at 10) | −10 |
| LEAK-* | Version leakage (Server version, X-Powered-By, X-AspNet-Version) | −5 |
The letter
- A+ coverage and effectiveness both 95 or more, and no ignored header
- A the lower of the two is 85 or more
- B 70 or more
- C 55 or more
- D 40 or more
- F below 40
- Each weakness is charged once. Where a header's coverage points already depend on its quality (the CSP levels, the HSTS max-age and includeSubDomains, a header the browser ignores), the same weakness is not deducted again from effectiveness.
- A header never costs more than leaving it out. For Content-Security-Policy, Strict-Transport-Security and Permissions-Policy the scores are also worked out with that header counted as absent (no points for it, none of its deductions); the site gets the better result, and the report says so.
Checked and shown, not graded: Reporting wiring (CSP report-to naming an endpoint defined in Reporting-Endpoints, or a legacy report-uri); Subresource Integrity (the share of cross-origin scripts and stylesheets with an integrity attribute). A policy protects the same with or without a report endpoint, and an integrity value cannot be put on a script its vendor changes without notice.
No grade is given when a firewall challenged the scanner or the site did not answer: grading a challenge or error page would be wrong. Deprecated headers (X-XSS-Protection enabled, Expect-CT, Public-Key-Pins, Feature-Policy, P3P, the X- CSP names) cost 2 points each; version strings in Server or X-Powered-By cost 5 once.
Every header explainedGuides for 32 platformsMethodology changelog
Free JSON API.
Without a key or an account: 3 scans a day with this checker. A free key gives 60 an hour, or 600 with a work email. Every answer carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset, and a 429 carries Retry-After. The same URL asked again within a minute returns the same scan. Tool id: security-headers. Options: surfaces=all (or a list of www, robots, 404, asset) and api=/path for the Coverage Map (counts as three scans), subdomains=1 for the HSTS subdomain check, ua=mobile, and minGrade=A+ to F (422 with the full scan when the grade is lower). Paste mode: POST /api/tools/v1/security-headers/paste with the headers as text (or JSON { text, url }). Badge: /api/tools/v1/badge/security-headers?url=example.com (the newest result of the last 7 days, never a new scan).
curl "https://bcdrpulse.com/api/tools/v1/security-headers?url=example.com"
The answer is { id, tool, createdAt, cached, report, capture, share }: report holds the grade, findings and fixes; capture the raw probe data (every hop and header, without bodies); share the result page. A saved result: GET /api/tools/v1/result/<id>. Errors: 400 bad address, 401 a sign-up is needed, 403 an address we never scan (private or internal), 429 over the limit, 503 scanner busy. The API page has keys, badges and alerts.
Questions.
Why is my grade lower here than on other header checkers?
Most checkers count headers that are present. This one grades what the browser will do with them: a CSP that allows 'unsafe-inline' scripts, HSTS that browsers ignore, or X-Frame-Options ALLOW-FROM all count for little or nothing. Each finding shows the exact header bytes and the points it costs.
What does the letter grade mean?
Grade v1.1 takes the lower of coverage and effectiveness: A+ needs both at 95 or more and no ignored header; A 85, B 70, C 55, D 40, F below. The full table is in the methodology section above.
Should I add every header in the 'apply all' block?
Mostly yes, but check two of them against your site first: Permissions-Policy (do not disable a feature your pages use, such as the camera on a video-call page) and the CSP, which we give as Report-Only so nothing breaks while you see what your pages load.
Do you check every page of my site?
The grade is for the URL you enter. Tick "Check the whole site" and we also fetch the www (or bare) host, robots.txt, a 404 page, one of the page's own scripts or stylesheets and, if you give one, an API route, and show which headers are missing where (the Coverage Map): a framable 404 page or an HTTP-only bare domain is a common gap. It counts as three scans.
Can I grade a site you cannot reach (localhost, an intranet)?
Yes: choose "Paste headers instead" and paste the output of curl -I (or -v) or the response headers from your browser's developer tools. Nothing is fetched or stored; the certificate, the redirect and security.txt are not checked in that mode.
What is the CSP lab?
Under the result, an editor that runs any policy against the scripts, styles, images, frames and forms in the page's own HTML and lists what it would block, with a starter policy that allows exactly what the page loads today. Resources loaded by scripts are not visible in the HTML, so ship a new policy as Report-Only first.
The result says our scanner was blocked. What now?
Your firewall or bot protection challenged us, so we did not grade its challenge page. The finding names the provider and the Ray ID; allow the User-Agent BCDRPulseHeaders for the scan (see /bot), or scan a page that is not behind the challenge.
Can I use this in CI or a script?
Yes: GET https://bcdrpulse.com/api/tools/v1/security-headers?url=example.com&minGrade=B returns the grade, findings and raw capture as JSON, and answers 422 when the grade is below B, so a pipeline step fails on a regression. Without a key or an account: 3 a day per tool; a free key gives 60 an hour (600 with a work email).
Is it safe to scan any URL?
Scan sites you own or are allowed to test. The scanner never connects to private, internal or cloud-metadata addresses, checks every redirect before following it, and sends only ordinary GET requests.
More free checkers.
Scans come from our probe on AWS (US East by default) with the User-Agent BCDRPulseHeaders (about our scanner). We store results for 30 days so share links work, and never store page bodies. Want this checked every few minutes with alerts? Add the site as a verified asset and uptime monitoring watches it. API

