Security headers checker
Check the CSP, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy and Permissions-Policy of any page, right here, graded by the same rules as a squirrelscan audit. Then copy the config that fixes each gap.
Want to see the output first? See a sample report.
HTTP security headers are the cheapest defence a site has. A few response headers tell the browser to stay on HTTPS, refuse to be framed, stop guessing file types and limit which scripts may run. Most sites set some of them and forget the rest.
Enter a URL above and this page fetches it once and grades its response headers with the six header rules a squirrelscan audit runs, so you get the verdicts squirrel audit reports for that page. No account, nothing stored. A full audit reads the same headers from the first page it crawls, then checks mixed content, cookie flags and subresource integrity on every page.
What it checks
Content-Security-Policy (CSP)
Flags a missing or report-only policy, 'unsafe-eval', 'unsafe-inline' scripts with no nonce or hash, and a bare * host in script-src. On every page it also lists the hosts the page loads that its own policy would block.
Strict-Transport-Security (HSTS)
Checks that the header is present, well formed and has a max-age of at least six months. A separate check requests the http:// version of a sample of your URLs and confirms they redirect to HTTPS.
X-Frame-Options, nosniff, Referrer-Policy and Permissions-Policy
Flags missing clickjacking protection (X-Frame-Options or CSP frame-ancestors), a missing or wrong X-Content-Type-Options, and a Referrer-Policy with unsafe-url. A missing Permissions-Policy gets a note; its directives are not validated.
Checked on every page
Mixed content (HTTP resources on HTTPS pages), Secure, HttpOnly and SameSite flags on cookies, Subresource Integrity on cross-origin scripts and stylesheets, and pages served over plain HTTP.
Also in the Security section
A missing security.txt, version numbers in Server and X-Powered-By headers, and API keys shipped in your HTML or scripts.
How to use it
- 1
Enter a page
Type an address above. The check fetches that page once, follows up to five redirects, and reads the response headers. It never downloads the page body.
- 2
Read the verdicts
Each header gets PASS, WARN or INFO with the message an audit reports, the severity it carries there, and a link to the rule's docs.
- 3
Add the missing headers
Copy the config for your platform from below, deploy, and check again to confirm the headers arrive. For mixed content, cookies and SRI on every page, run a full audit.
Headers vs per-page checks
Security headers are usually set in one place: a CDN rule, a reverse proxy or app middleware. squirrelscan reads them once per audit, from the first page it crawls, and reports each header that is missing or weak. If part of your site is served by a different app or host, its headers can differ, so check a page on that host here or audit it separately.
Mixed content, cookie flags and Subresource Integrity depend on each page's markup and responses, so those are checked on every page the audit crawls, and the report lists each affected page.
How to fix what it finds
HSTS, nosniff, clickjacking or referrer headers are missing
Set the baseline headers once, where every response passes through. The HSTS line leaves out includeSubDomains: add it only when every subdomain serves HTTPS, because browsers then refuse plain HTTP on all of them for the whole max-age. X-Frame-Options DENY breaks any page your own site shows in an iframe, so use SAMEORIGIN there. The Permissions-Policy line turns off camera, microphone and geolocation, so remove the ones your site uses.
Cloudflare (_headers file, Pages or Workers static assets)
/*
Strict-Transport-Security: max-age=31536000
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()nginx (server block)
add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;Vercel (vercel.json)
{
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "Strict-Transport-Security", "value": "max-age=31536000" },
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "X-Frame-Options", "value": "DENY" },
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
{ "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" }
]
}
]
}Next.js (next.config.js)
module.exports = {
async headers() {
return [
{
source: "/:path*",
headers: [
{ key: "Strict-Transport-Security", value: "max-age=31536000" },
{ key: "X-Content-Type-Options", value: "nosniff" },
{ key: "X-Frame-Options", value: "DENY" },
{ key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
{ key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=()" },
],
},
];
},
};Reported by security/hsts, security/x-content-type, security/x-frame-options, security/referrer-policy, security/permissions-policy
There is no Content-Security-Policy
Start with the Report-Only header and watch the browser console for violations, then switch to the enforcing header: squirrelscan warns on report-only because it blocks nothing. A nonce must be new on every response, and your app puts the same value on each script tag it trusts. That takes server code or middleware: a static _headers file or vercel.json sends the same value every time, so there use a 'sha256-...' hash of each inline script, or 'self' alone, instead. Once the policy is enforced, the audit lists any host a page loads that the policy blocks.
Response header, first pass
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' 'nonce-RANDOM_PER_RESPONSE'; object-src 'none'; frame-ancestors 'none'Response header, once it is clean
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-RANDOM_PER_RESPONSE'; object-src 'none'; frame-ancestors 'none'Reported by security/csp, security/csp-blocks-own-resources
A page loads resources over HTTP
Change the http:// URLs in the page to https://. While you hunt them down, the upgrade-insecure-requests directive tells browsers to fetch them over HTTPS.
Response header
Content-Security-Policy: upgrade-insecure-requestsReported by security/mixed-content
Cookies are missing Secure, HttpOnly or SameSite
Set all three on session cookies where your framework issues them. HttpOnly keeps scripts from reading the cookie, and SameSite=None needs Secure or browsers reject it.
Response header
Set-Cookie: session=abc123; Path=/; Secure; HttpOnly; SameSite=LaxReported by security/cookie-flags
Sources
The guidance above follows these references. CSP Level 2 makes frame-ancestors take precedence over X-Frame-Options when a response sends both, and RFC 6797 has browsers ignore a Strict-Transport-Security header received over plain HTTP. Each rule's docs page lists the sources it relies on.
Recommended values for each security header.
W3C: Content Security Policy Level 2How frame-ancestors relates to X-Frame-Options.
RFC 6797: HTTP Strict Transport SecurityThe HSTS specification, including max-age and includeSubDomains.
MDN: Permissions-PolicyDirective and allowlist syntax for browser features.
Keep going
Turn header findings into fixes with your coding agent.
See a sample reportA real audit, including the security section.
MDN: HTTP headersThe reference for every header we check.
Security rules referenceEvery security rule, documented.
Frequently asked questions
- Which security headers matter most?
- Strict-Transport-Security, Content-Security-Policy, X-Content-Type-Options and X-Frame-Options cover the most common attacks. squirrelscan checks these plus Referrer-Policy and Permissions-Policy.
- Does it check every page or just the homepage?
- This page checks the one URL you enter. An audit reads headers once, from the first page it crawls, because they are usually set in one place for the whole site. Mixed content, cookie flags, Subresource Integrity, plain-HTTP pages and the hosts a CSP blocks are checked on every crawled page. To check the headers of a section served by a different host, enter a URL on that host.
- Is the result the same as a squirrelscan audit?
- For these six headers, yes. The page runs the same checks as the audit rules, with the same messages, on the response to the URL you enter. Two things can still differ: a site that answers crawlers differently may send the audit other headers, and the audit adds the per-page checks this page leaves out.
- Is X-Frame-Options still needed if I set frame-ancestors?
- Not for squirrelscan: either one passes its clickjacking check. Browsers that support CSP frame-ancestors use it in place of X-Frame-Options, so X-Frame-Options only adds cover for old browsers. Setting both does no harm.
- Is a security headers check a security audit?
- No. It reads your responses and flags missing or weak protections, the way a linter flags code. It does not try to break in, so it is no substitute for a penetration test.
- Is it free?
- The llms.txt validator, the AI crawler checker, the robots.txt generator and the instant security headers check are free and need no account. The other checks run inside a squirrelscan audit. The squirrel CLI runs audits on your machine for free when you are signed out or pass --offline, with no cap on how many. Signed in, CLI and cloud audits spend credits: every account gets 500 free credits a month. An audit costs 50 credits plus 2 per audited page, and 1 per external link the cloud verifies when link checks are on.
Run the full audit
This check is one of 300+ rules in a squirrelscan audit. Run it in the cloud or on your own machine.
In the cloud
squirrelscan crawls the site for you and keeps each report in your dashboard. Every account gets 500 free credits a month. An audit costs 50 credits plus 2 per audited page, and 1 per external link the cloud verifies.
On your machine
The squirrel CLI runs the same rules locally, free while you are signed out or with --offline. Install it, then run:
squirrel audit https://example.com