Security Headers Checker
Grade a site’s security headers A+ to F and get copy-paste fixes for your server.
What to check
Requesting the page from MySmartCoPilot’s server… slow sites can take up to a minute.
Security headers report
Checks
Other headers
Redirects and the plain-HTTP address
HSTS preload eligibility
Requirements from hstspreload.org. The site itself says: “While HSTS is recommended, HSTS preloading is not recommended.” Preloading covers every subdomain, and a removal takes months to reach users. Check the official status.
Content-Security-Policy, directive by directive
Cookies
All response headers
Suggested headers
Changes configuration cannot make
Only headers that need a change are listed unless you tick the box above. Test on a staging copy first — a Content-Security-Policy or COOP can break features.
About the Security Headers Checker
Enter a website address, or paste response headers, and get an A+ to F grade for the headers that tell browsers how to protect your visitors: Content-Security-Policy, Strict-Transport-Security (HSTS, with preload eligibility), X-Frame-Options / frame-ancestors, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, Cross-Origin-Opener-Policy and the Secure, HttpOnly and SameSite flags on cookies. Each problem is explained — what the header does, what is wrong and how to fix it — with a link to the standard where one applies.
Each header is parsed the way browsers parse it — CSP Level 3’s rules for duplicate directives, fallbacks and 'strict-dynamic', RFC 6797 for HSTS, the HTML Standard’s X-Frame-Options algorithm, RFC 8941 structured fields for Permissions-Policy — so a typo that makes a browser silently ignore your header is caught, not just a missing header. Suggested headers then turns the results into configuration for Nginx, Apache, Caddy, IIS, Cloudflare Pages or Netlify _headers, Vercel or Express.
How to use it
- To check a live site, type its address (for example
example.com) and press Check headers. MySmartCoPilot’s server requests the page and itshttp://version and returns only the headers. - For a page behind a login, a staging site or an intranet, choose Paste headers and paste the output of
curl -sI https://your-site/or the response headers from your browser’s developer tools (Network tab → select the page → Headers). Untick served over HTTPS if the page was plain HTTP. - Read the grade, then open each check: Problem and Warning items explain what an attacker could do and how to fix it; Note items are optional improvements.
- Pick your server under Suggested headers, copy or download the configuration, try it on a staging copy, deploy it and press Check again.
- Copy the report, or download it as Markdown to paste into a ticket or pull request. Cookie values are left out of it.
Examples
strict-transport-security: max-age=15552000 content-security-policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://www.googletagmanager.com x-frame-options: SAMEORIGIN x-content-type-options: nosniff referrer-policy: no-referrer-when-downgrade set-cookie: PHPSESSID=8f2a1c9d; path=/
Grade D · 52/100 — CSP weak ('unsafe-inline'), HSTS 180 days, full URLs sent to other sites, session cookie without Secure, HttpOnly and SameSiteThe fixes are mostly configuration: a one-year HSTS, Referrer-Policy: strict-origin-when-cross-origin, a Permissions-Policy, COOP and proper cookie flags lift it to a B. Removing 'unsafe-inline' needs code changes (nonces or external scripts) and is what an A takes.
content-security-policy: script-src 'nonce-q8Zp3RkT7wXy2LmN4vBc9A' 'strict-dynamic'; object-src 'none'; base-uri 'none' strict-transport-security: max-age=63072000; includeSubDomains x-frame-options: DENY x-content-type-options: nosniff referrer-policy: no-referrer permissions-policy: camera=(), microphone=(), geolocation=() cross-origin-opener-policy: same-origin
Grade A+ · 100/100 — 8 of 8 checks passed
permissions-policy: camera 'none'; microphone 'none'
Syntax error: the whole header is ignored. Write it as: camera=(), microphone=()
Permissions-Policy is a structured header: one syntax error and browsers drop all of it, so this site had no restrictions at all.
Common uses
- Checking a new site or a server migration before launch — and again after every CDN, proxy or framework change, which often drops headers.
- Writing a first Content-Security-Policy: start with the suggested Report-Only policy, then tighten it.
- Answering a penetration-test or security-questionnaire item about missing security headers, with a report to attach.
- Confirming that session cookies are
Secure,HttpOnlyandSameSiteafter a login change. - Seeing whether a domain is ready for the HSTS preload list — and what you would be committing to.
What each header does — and a safe value to start with
- Content-Security-Policy — which scripts, styles, frames and other resources a page may load. The strongest form is a strict, nonce-based policy:
script-src 'nonce-{random}' 'strict-dynamic'; object-src 'none'; base-uri 'none', with a fresh random nonce of at least 128 bits in every response (CSP Level 2 §4.2). Roll it out asContent-Security-Policy-Report-Onlyfirst. - Strict-Transport-Security —
max-age=31536000; includeSubDomains: browsers then use only HTTPS for your host for a year (RFC 6797). AddincludeSubDomainsonly once every subdomain works over HTTPS. - Clickjacking protection —
Content-Security-Policy: frame-ancestors 'self'(or'none'), plusX-Frame-Options: SAMEORIGINfor very old browsers.ALLOW-FROMis ignored by current browsers. - X-Content-Type-Options —
nosniff, the only valid value. - Referrer-Policy —
strict-origin-when-cross-origin(also the browser default) orno-referrer. - Permissions-Policy — switch off what you do not use:
camera=(), microphone=(), geolocation=(). Origins go in double quotes:geolocation=(self "https://maps.example.com"). - Cross-Origin-Opener-Policy —
same-origin, orsame-origin-allow-popupsif you rely on OAuth or payment pop-ups. - Cookies — session cookies need
Secure; HttpOnly; SameSite=Lax(orStrict); the__Host-prefix also locks a cookie to your host.SameSite=NonewithoutSecuremakes browsers reject the cookie (RFC 6265bis).
How the grade is calculated
Each check has a share of 100 points: Content-Security-Policy 30, HSTS 20, clickjacking protection 15, X-Content-Type-Options 10, Referrer-Policy 10, Permissions-Policy 5, Cross-Origin-Opener-Policy 5 and cookies 5.
- CSP: nonce- or hash-based (strict) 30; a host allowlist 22;
'unsafe-inline',*,https:ordata:for scripts 8; set but not restricting scripts 5; Report-Only only 3. Strict and allowlist policies lose 2 without anobject-srcrestriction and 2–3 withoutbase-uri;'unsafe-eval'costs 4. - HSTS: one year or more with
includeSubDomains20 (18 without); 180 days to a year 14; shorter 8; missing, invalid ormax-age=00. - Clickjacking:
frame-ancestorswith'none','self'or listed sites, orX-Frame-OptionsDENY or SAMEORIGIN 15; conflicting values 11;frame-ancestors *3. - Referrer-Policy: no-referrer, same-origin, strict-origin or strict-origin-when-cross-origin 10; not set (browser default) 7; origin or origin-when-cross-origin 7; no-referrer-when-downgrade 4; unsafe-url 0.
- Permissions-Policy 5 (3 when a powerful feature such as the camera is allowed for every site, 2 when no listed feature is recognised, 0 when missing or invalid); COOP same-origin or noopener-allow-popups 5, same-origin-allow-popups 4, otherwise 0; cookies 5 (also when none are set), minus 2 per cookie without
Secureor rejected by browsers, 1 per session cookie readable by JavaScript and 1 per invalidSameSitevalue or session cookie without one; aSet-Cookiethat deletes a cookie (Max-Age=0or a pastExpires) does not count.
Grades: A+ from 95, A from 85, B from 70, C from 55, D from 40, F below. A page that is not served over HTTPS gets at most a D. Without any CSP the best possible grade is a B. The weighting is MySmartCoPilot’s own reading of the standards listed below — guidance, not a security audit.
HSTS preload: eligible is not the same as advisable
The HSTS preload list is built into browsers, so they use HTTPS for a domain even on the first visit. Its submission requirements: a valid certificate; a redirect from HTTP to HTTPS on the same host if you listen on port 80; HTTPS on every subdomain — including www if it has a DNS record, and internal subdomains; and on the base domain an HSTS header with max-age of at least 31536000, includeSubDomains and preload, also on an HTTPS redirect.
The checker shows which of these it could verify, using hstspreload.org’s stricter reading of the header (for example, it does not accept a quoted max-age). hstspreload.org itself says: “While HSTS is recommended, HSTS preloading is not recommended.” It also warns that inclusion cannot easily be undone and that a removal takes months to reach users. Add preload only if you are sure.
What a URL check sends
Only the address goes to MySmartCoPilot’s server (Cloudflare). It requests the page with GET as MySmartCoPilotBot, without cookies, follows at most 5 redirects and discards the body unread; it also requests the http:// version once without following its redirect. Before each new host is contacted its DNS records are looked up over HTTPS and every address must be public: private, loopback, link-local, carrier-grade NAT and cloud-metadata addresses and internal names are refused, and every redirect target is checked again. Results are cached on the server for up to 10 minutes, so repeated checks of the same address usually do not reach the site again (Check again can refresh a result after a minute), and each visitor has a limited number of checks per hour.
Sources
- OWASP Secure Headers Project — recommended values and the list of headers to remove (headers_add.json and headers_remove.json)
- W3C Content Security Policy Level 3 (Working Draft) and CSP Level 2 §4.2 for nonce length
- web.dev, Mitigate cross-site scripting (XSS) with a strict Content Security Policy
- RFC 6797 (HSTS) and hstspreload.org
- HTML Standard (X-Frame-Options, COOP, COEP) and Fetch Standard (nosniff, CORP)
- W3C Referrer Policy (Editor’s Draft), W3C Permissions Policy (Editor’s Draft) and its policy-controlled feature list, and RFC 8941 structured fields
- draft-ietf-httpbis-rfc6265bis-22 (cookies; in the RFC Editor queue)
Limitations
- One URL’s response headers are checked. Other pages, API endpoints and files can send different headers — check the pages that matter most (login, account, checkout).
- A Content-Security-Policy set in a
<meta>tag is not seen by a URL check, because the page body is not read. (A meta policy cannot set frame-ancestors, report-uri or sandbox anyway.) - Cookies set by JavaScript, or only after you log in, are not visible to a URL check. Paste the headers of a logged-in response to check those.
- Firewalls and bot protection may answer MySmartCoPilot’s server with an error or a challenge page. The checker warns when the final status is 403, 429 or 503 — paste the headers from your browser instead.
- The grade measures headers, not your application: it cannot find cross-site scripting or other bugs, and a good grade is not a security audit.
- HSTS preload eligibility is only partly checked: the certificate and every subdomain are tested by hstspreload.org when you submit. The SSL Certificate Checker shows a site’s certificate and its official preload status.
- Very long header values are analysed up to 16 KB each (64 KB per response).
Privacy
Pasted headers are analysed in your browser and never uploaded. For a URL check only the address is sent to MySmartCoPilot’s server, which fetches the page’s headers from the website and returns them. The server keeps the result in memory for up to 10 minutes and does not save it anywhere else; its log records only the host name, status code and time of each request — never the full URL or your IP address. Cookie values are left out of the downloadable report.
Frequently asked questions
What is a good security headers grade?
A or A+. Most sites reach a B with configuration alone: HSTS, nosniff, frame protection, Referrer-Policy, Permissions-Policy, COOP and well-flagged cookies add up to 70 points. Going above a B needs a Content-Security-Policy that blocks inline scripts, because CSP carries 30 of the 100 points.
Why does my site get a different grade here than on another checker?
Each checker weighs headers differently. This one parses headers the way browsers do, so it also marks down headers that browsers ignore (an invalid HSTS value, ALLOW-FROM, Feature-Policy syntax inside Permissions-Policy) and policies whose 'unsafe-inline' or https: lets injected scripts run. The breakdown shows where every point comes from.
Is 'unsafe-inline' a problem if my script-src also has a nonce?
No. When a script-src directive contains a nonce or a hash, CSP Level 3 browsers ignore 'unsafe-inline' — it only remains as a fallback for very old browsers, and the checker accounts for that. Without a nonce or hash, 'unsafe-inline' lets any injected script run.
Do I still need X-Frame-Options if I use frame-ancestors?
Browsers ignore X-Frame-Options when an enforced Content-Security-Policy has frame-ancestors (HTML Standard). Keeping X-Frame-Options: SAMEORIGIN as well does no harm and covers very old browsers.
Should I send X-XSS-Protection?
No. OWASP notes that modern browsers have deprecated the XSS filter and that it can introduce problems of its own; it recommends X-XSS-Protection: 0 (or no header) and a Content-Security-Policy instead.
Should I add preload to my HSTS header?
Add HSTS, yes — start with a short max-age and raise it. Add preload only if every subdomain, including internal ones, will always support HTTPS: preloaded domains are built into browsers, removal takes months, and hstspreload.org itself says that HSTS preloading is not recommended.
Can I check a page that needs a login, or an intranet site?
Not by URL — MySmartCoPilot’s server has no session and only fetches public sites. Open the page in your browser, open the developer tools’ Network tab, select the page, copy its response headers and use Paste headers. Nothing you paste leaves your browser.
Why was my URL refused?
For safety the checker only fetches public websites on ports 80 and 443. Private or local addresses (such as 192.168.x.x or 127.0.0.1), internal host names and MySmartCoPilot’s own pages are refused, and every redirect target is checked again before it is followed.