SECURITY HEADERS CHECKER
Paste your URL. We grade every security-relevant HTTP header and show exactly how to fix the misses — copy-paste config for Vercel, Netlify, Nginx, and Express.
GRADE YOUR SECURITY HEADERS NOW
Enter your URL — we fetch every security-relevant HTTP header and return Pass / Warn / Fail with paste-ready fix configs for Vercel, Netlify, Nginx, and Express.
Why Headers Matter
HTTP security headers are the last line before the browser. A missing X-Frame-Options means your login page can be loaded inside an attacker’s iframe and clickjacked. Missing Strict-Transport-Security means your users’ first visit over plain HTTP can be downgraded and the session cookie sniffed. Permissive CORS means other sites can read your authenticated responses with the user’s cookies attached.
The headers themselves are simple key-value strings — they fix entire vulnerability classes for the cost of one config block. They’re also the cheapest, fastest hardening pass an app will ever get.
The Grade Card
Each header gets scored Pass / Warn / Fail with specific guidance:
STRICT-TRANSPORT-SECURITY
Prevents protocol downgrade. Need max-age=31536000; includeSubDomains; preload.
CONTENT-SECURITY-POLICY
The big one. Blocks XSS, inline scripts, and unauthorised origins.
X-FRAME-OPTIONS / FRAME-ANCESTORS
Clickjacking defense. Explicit DENY or CSP frame-ancestors 'none'.
CORS (ACL-ALLOW-ORIGIN)
Never * with credentials. Explicit origin whitelist only.
X-CONTENT-TYPE-OPTIONS
nosniff — stops MIME-confusion attacks where a JSON response gets executed as JS.
REFERRER-POLICY
Limits what third parties learn about your URLs. strict-origin-when-cross-origin is the safe default.
PERMISSIONS-POLICY
Disables camera, mic, geolocation, payment APIs by default — re-enable per surface that needs them.
COOKIE FLAGS
Session cookies need Secure; HttpOnly; SameSite=Lax. Most frameworks miss at least one.
Header reference table
| Header | Recommended value | If missing |
|---|---|---|
Strict-Transport-Security |
max-age=31536000; includeSubDomains; preload |
First request can be MITM’d over HTTP |
Content-Security-Policy |
default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none' (then tighten per route) |
XSS payloads load remote scripts |
X-Frame-Options |
DENY (or rely on CSP frame-ancestors) |
Clickjacking via hidden iframe |
X-Content-Type-Options |
nosniff |
Browser executes a text/plain response as JS |
Referrer-Policy |
strict-origin-when-cross-origin |
Full URLs (with tokens in query strings) leak via Referer |
Permissions-Policy |
camera=(), microphone=(), geolocation=(), payment=() |
Embedded third parties can request sensitive APIs |
Cross-Origin-Opener-Policy |
same-origin |
Spectre-style cross-window attacks possible |
Cross-Origin-Resource-Policy |
same-origin (or cross-origin for public assets) |
Other sites can embed your authenticated responses |
Cache-Control (auth pages) |
no-store |
Sensitive HTML cached on shared proxies / browsers |
How attackers find this
Header misconfigurations are trivially scanned. There are public scanner indexes (securityheaders.com, Mozilla Observatory, plus dozens of “security report” SaaS bots) that crawl deployed sites continuously and publish grades. Attackers don’t need to scan you — they just query the index.
For specific exploits:
- Missing HSTS — sslstrip-style downgrades on hostile networks (open Wi-Fi, hotel captive portals). The first request a user makes to
yoursite.comis plain HTTP; the attacker rewrites the redirect. - Missing X-Frame-Options — attacker hosts
attacker.com/win-a-prize, embedsyoursite.com/transfer-fundsin a transparent iframe over a “click here” button. User clicks button on attacker site, actually clicks the transfer button on your site, with their cookies attached. Access-Control-Allow-Origin: *with credentials — when paired withAllow-Credentials: true(browsers reject this combo, but bad servers send*anyway and developers then “fix” it by reflecting theOriginheader without validation), any site can read authenticated responses.- Missing CSP — every reflected XSS becomes a full account takeover, because the injected script can call any origin and exfiltrate cookies/localStorage.
ServerandX-Powered-Byheaders — version disclosure. Attacker readsExpress 4.17.1, looks up CVEs for that version, knows exactly which exploits apply.
Host-Specific Recipes
The report includes paste-ready config for every target. Common ones:
vercel.json:
{
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "Strict-Transport-Security", "value": "max-age=31536000; includeSubDomains; preload" },
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
{ "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=(), payment=()" },
{ "key": "Content-Security-Policy", "value": "default-src 'self'; script-src 'self' 'nonce-{NONCE}'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'" }
]
}
]
}
Netlify _headers:
/*
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()
Content-Security-Policy: default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'
Express + Helmet:
import helmet from 'helmet';
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", (req, res) => `'nonce-${res.locals.nonce}'`],
objectSrc: ["'none'"],
baseUri: ["'self'"],
frameAncestors: ["'none'"],
},
},
hsts: { maxAge: 31536000, includeSubDomains: true, preload: true },
crossOriginOpenerPolicy: { policy: 'same-origin' },
}));
Nginx:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Content-Security-Policy "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'" always;
The always flag is mandatory — without it Nginx skips the header on error responses, which is exactly when version-disclosure leaks happen.
CSP rollout strategy
CSP is the one header that will break things if you turn it on cold. Roll out in three stages:
- Report-only — deploy
Content-Security-Policy-Report-Onlywithreport-uri /csp-report. Browsers send violation reports; nothing is blocked. Run for 1–2 weeks across your real traffic. - Triage reports — every violation is either a real script you missed in the policy (whitelist with hash/nonce) or an actual XSS attempt (good, it would have been blocked).
- Enforce — promote to
Content-Security-Policy. Keepreport-uriso regressions surface in CI.
If you can’t host a report endpoint, csp-evaluator.withgoogle.com will at least flag obvious holes in a pasted policy.
Why AI-Generated Apps Fail This
AI generators ship the app first, headers later — or never. Default framework output ships without CSP. CORS gets set to * “temporarily” during debugging and stays. The dev environment never triggered any of these as bugs because everything was same-origin localhost. This checker is the fastest way to catch those drifts.
What this scanner does NOT flag
- Headers set on a different domain. If your assets are on a CDN subdomain that returns its own headers, we test only the URL you submit. Pass each origin separately.
- Edge-case CSP issues. A policy that parses correctly but allows
'unsafe-eval'for a single legitimate library is graded Warn, not Fail — the call is yours. - Cookie issues for cookies the scanner never sees. We grade the cookies your site sets on a fresh visit. Cookies set only after login require an authenticated re-scan.
- Header order or duplicates from upstream proxies. Some load balancers prepend their own
X-Frame-Options. We report the value the browser actually receives; if your app sendsDENYand the proxy rewrites it toSAMEORIGIN, the scanner shows the rewritten value.
Related tools and guides
- Token Leak Checker — header hardening matters less if your API keys are in the bundle anyway.
- Vibe Code Scanner — full app scan that reads headers and probes auth and RLS.
- Free Security Self-Audit — manual checklist that pairs with header scanning.
COMMON QUESTIONS
FULL SCAN, NOT JUST HEADERS
Headers are the surface. The VibeEval agent tests auth, RLS, and API behavior underneath.