Tells browsers to always connect over HTTPS. Graded on max-age (≥ 31536000), `includeSubDomains`, and `preload` (the strictest configuration enrolls the domain in the HSTS preload list, baked into Chrome, Firefox, and Safari shipping).
Free HTTP security headers checker — grade Strict-Transport-Security, CSP, X-Frame-Options, and 10+ other headers.
HTTP Security Headers Analyzer fetches your site over HTTPS, captures every response header, and grades it against the modern best-practice baseline — HSTS, Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, Cross-Origin-Opener-Policy, Cross-Origin-Embedder-Policy, Cross-Origin-Resource-Policy, and more. Reports an overall security grade (A+ to F) plus the specific missing or weak headers that knock the grade down.
What gets graded
Twelve security headers, graded against modern best-practice values — not just 'present or absent' but 'configured correctly'. The grade is composite; the per-header breakdown tells you exactly what to fix.
Whitelists which sources scripts, styles, frames, and other resources may load from. The strongest single defense against XSS. Graded on `default-src` strictness, presence of `'unsafe-inline'` / `'unsafe-eval'` (both significantly weaken protection), nonce/hash usage, and `frame-ancestors`.
Prevents your site from being embedded in iframes on other origins (UI redress / clickjacking attacks). `DENY` or `SAMEORIGIN` accepted. Modern best practice: replace with CSP `frame-ancestors` which is more granular.
`nosniff` prevents browsers from second-guessing the declared content-type. Without it, a file labeled `text/plain` containing HTML could be executed as a script under some conditions. Cheap to set; should always be present.
Controls how much Referer information is sent to third-party origins. Best practice: `strict-origin-when-cross-origin` or `no-referrer`. Mitigates leak of sensitive path/query data in outbound requests.
Restricts which browser features (geolocation, camera, microphone, payment, USB, etc) can be used by your origin and embedded iframes. Hardening reduces attack surface from compromised third-party scripts.
`same-origin` enables cross-origin isolation, which unlocks high-resolution timers and shared memory and gives stronger protection against Spectre-class attacks. Increasingly important for security-sensitive sites.
Pairs with COOP. `require-corp` means cross-origin resources must opt in via CORP or CORS. The combination of COOP + COEP is what enables `crossOriginIsolated` in modern browsers.
Why security headers are the cheapest hardening you can do
Most security headers are one-line config changes that immediately raise the cost of common attacks. Five reasons they're underrated:
- HSTS eliminates the SSL-stripping attack class entirely. Without HSTS, an attacker on the network can intercept a user's first HTTP-to-HTTPS upgrade and serve the site over plain HTTP, capturing credentials in transit. With HSTS (and preload), browsers refuse plain HTTP for your domain from day one. The cost: setting one header. The benefit: a whole attack class gone.
- CSP is the single best XSS defense — when configured well. A strict CSP that disallows `'unsafe-inline'` scripts means an attacker who finds an XSS injection still can't execute it. Most real-world CSP deployments include `'unsafe-inline'` because the codebase relies on inline scripts — partially defeating CSP's purpose. The grader surfaces this tradeoff explicitly.
- X-Frame-Options stops clickjacking outright. Without `X-Frame-Options` or CSP `frame-ancestors`, your authenticated user could be tricked into clicking 'Confirm transfer' on your site by embedding it in an attacker's iframe with a transparent overlay. One header line stops it.
- Modern compliance frameworks expect these headers. PCI-DSS, SOC 2, ISO 27001, HIPAA — all reference HTTP security headers in their hardening guidance. An A or A+ grade on this checker maps directly to satisfying common compliance checklists. F-grade sites get findings.
- The Mozilla Observatory bar moved up. Five years ago, an A meant 'has HSTS and X-Frame-Options'. Today it means 'CSP with no `'unsafe-inline'`, COOP + COEP for cross-origin isolation, Permissions-Policy locking down features'. The bar keeps rising; sites that haven't updated their headers in years grade lower than they used to.
Fetch, parse headers, grade against modern baseline
A header check is one HTTPS request plus a structured grade. We follow the same logic Mozilla's Observatory, securityheaders.com, and similar tools use — with explicit explanations of why each header earns the grade it does.
- Stage 1 — Fetch over HTTPS Send a real HTTPS GET request to the site's homepage. Capture all response headers. Don't follow redirects to a different origin — the headers on the final origin are what matter, but cross-origin redirects mean the grade applies to a different host than the user typed.
- Stage 2 — Parse each header Each security header is parsed against its RFC-defined value grammar. HSTS into max-age, includeSubDomains, preload. CSP into directives and source lists. Permissions-Policy into the modern key/value grammar (not the deprecated Feature-Policy syntax).
- Stage 3 — Grade each header Each header gets a score (0 to 100) based on how close its value is to best practice. HSTS with max-age=31536000 + includeSubDomains + preload scores 100. HSTS with max-age=300 and no other directives scores 30. Missing CSP scores 0; CSP with `'unsafe-inline'` scores moderate; CSP with strict nonce-based directives scores high.
- Stage 4 — Composite grade Weight per-header scores into a composite letter grade. F (missing critical headers like HSTS) → A+ (every header present with best-practice values plus preload). Most production sites grade C to A; A+ is rare and intentional.
- Stage 5 — Surface what's missing or weak Per-header recommendations: 'HSTS max-age too low — should be at least 31536000 (1 year)', 'CSP allows `'unsafe-inline'` — refactor to use nonces or hashes'. Each recommendation has the exact header value to publish.
- Stage 6 — Cross-check related headers Some headers interact. COOP + COEP must be set together for cross-origin isolation. CSP `frame-ancestors` supersedes X-Frame-Options. Server header leaks (e.g. `Server: Apache/2.4.41 (Ubuntu)`) reveal version info attackers can match against known vulnerabilities. The grader surfaces these compound findings.
Why Content-Security-Policy is hard to get right
CSP is the most powerful security header — and the hardest to configure. Done well, it eliminates XSS. Done poorly, it provides false security or breaks the site. Five things to know:
- `default-src 'self'` is the safe foundation Every CSP should start with `default-src 'self'` (or stricter) and then explicitly opt-in for each resource type that needs broader access. Without `default-src`, missing directives fall back to permissive defaults — defeating the purpose.
- `'unsafe-inline'` is the silent CSP killer Allowing `'unsafe-inline'` for scripts (or styles) means inline `<script>` tags and `onclick=` handlers run — which means an XSS injection's payload runs. Most legacy sites need `'unsafe-inline'` because their codebase relies on inline event handlers. Real CSP protection requires refactoring or nonce/hash usage.
- Nonces and hashes are the modern path Generate a fresh random nonce per response, include it in CSP (`script-src 'nonce-randomvalue'`), and tag every inline script with the matching `nonce` attribute. Injected scripts (without the nonce) are blocked; legitimate inline scripts (with the nonce) run. Hash-based approaches do the same but with content hashes.
- `frame-ancestors` supersedes X-Frame-Options The CSP `frame-ancestors` directive does the same job as X-Frame-Options but more flexibly (multiple origins, full URL matching). Setting `frame-ancestors 'self'` is functionally equivalent to `X-Frame-Options: SAMEORIGIN`. Set both for backward compatibility with older browsers.
- Report-Only mode is your friend during rollout Deploy CSP via the `Content-Security-Policy-Report-Only` header first. Violations are reported to your `report-uri` endpoint but don't block anything. Run for a few weeks, fix every violation you see, then switch to the enforcing `Content-Security-Policy` header.
- Strict-dynamic and trusted types are the cutting edge `'strict-dynamic'` allows scripts loaded by an already-trusted (nonce'd) script. `require-trusted-types-for 'script'` enables Trusted Types, which blocks unsafe DOM sinks at the engine level. Both are modern hardening; few sites have adopted them yet.
Use this programmatically
Every header, per-header grade, and recommendation is available as JSON. Useful for CI gates that prevent regressing security headers, vendor due diligence, and continuous header-monitoring across a portfolio of sites.
curl 'https://api.domainscan.in/v1/security/headers?url=https://github.com'const res = await fetch(
'https://api.domainscan.in/v1/security/headers?url=https://github.com'
);
const hdr = await res.json();
console.log(hdr.grade); // 'A'
console.log(hdr.score); // 91
// Per-header detail
hdr.headers.forEach(h => {
console.log(`${h.name}: ${h.score}/100 — ${h.status}`);
});
// CI gate: fail build if grade regresses
if (['F', 'E', 'D'].includes(hdr.grade)) {
console.error('Security headers grade regressed:', hdr.grade);
process.exit(1);
}
// Fix list
hdr.recommendations.forEach(r => {
console.log(`[${r.severity}] ${r.header}: ${r.action}`);
});{
"url": "https://github.com",
"grade": "A",
"score": 91,
"headers": [
{
"name": "Strict-Transport-Security",
"value": "max-age=31536000; includeSubDomains; preload",
"score": 100,
"status": "strong",
"notes": "max-age=1y, preload-eligible"
},
{
"name": "Content-Security-Policy",
"value": "default-src 'none'; script-src ...",
"score": 85,
"status": "good",
"notes": "Strict default-src, no 'unsafe-inline'"
}
],
"recommendations": [
{
"severity": "medium",
"header": "Permissions-Policy",
"action": "Add Permissions-Policy header restricting unused browser features"
}
]
}How teams use the Security Headers Checker
Six patterns we see most often:
Wire the API into your CI/CD pipeline. Block deploys that regress the security-headers grade. Catches the well-intentioned middleware change that accidentally removed HSTS three releases ago.
PCI-DSS, SOC 2, ISO 27001, HIPAA audits all reference HTTP security headers. A documented A or A+ grade satisfies the relevant controls without manual evidence-gathering.
Evaluating a SaaS that will handle your customer data. Their security-headers grade is a leading indicator of broader security maturity. F-grade sites correlate with deeper issues.
Before paying for an external pen test, run security-headers and other low-hanging-fruit checks. Fix the obvious findings yourself; let the pen-testers spend their hours on harder issues.
Run the checker against every public site of a target acquisition. The header grades tell you how much post-acquisition hardening work to expect.
Cron the API against your portfolio of sites. Alert on grade regressions. Catches the silent drift when a new CDN config or middleware change accidentally removes a critical header.
Common questions
- What are HTTP security headers? HTTP response headers that the server sends to instruct the browser about security policies. They control things like 'always use HTTPS' (HSTS), 'don't allow this site in iframes' (X-Frame-Options), 'only allow scripts from these sources' (CSP), and 'don't send Referer to third parties' (Referrer-Policy). Each header is a one-line server config and immediately raises the cost of common attacks.
- Which security headers are most important? Top priorities, in order: Strict-Transport-Security (eliminates SSL-stripping), Content-Security-Policy (defends against XSS), X-Frame-Options or `frame-ancestors` (defends against clickjacking), X-Content-Type-Options (defends against MIME-sniffing). These four cover the biggest attack classes. The remaining headers (Referrer-Policy, Permissions-Policy, COOP, COEP) add depth-of-defense.
- What is HSTS and should I enable preload? Strict-Transport-Security tells browsers to always connect to your domain over HTTPS, never plain HTTP. `preload` enrolls your domain in the HSTS preload list shipped with Chrome, Firefox, and Safari — so even a first-time visitor never sends plain HTTP. Preload is excellent for security but hard to reverse — once you're on the list, removal takes months. Submit via hstspreload.org only when you're confident HTTPS is the only protocol you'll ever serve.
- What is Content-Security-Policy and is `'unsafe-inline'` bad? CSP whitelists which sources can load scripts, styles, frames, etc. `'unsafe-inline'` allows inline `<script>` tags and event handlers — which means an XSS injection's payload runs. It's not 'bad' in the sense of immediately broken, but it significantly weakens CSP's XSS protection. Modern approach: use nonces or hashes for the inline scripts you actually need, remove `'unsafe-inline'`.
- Should I use X-Frame-Options or `frame-ancestors`? Both, for backward compatibility. CSP `frame-ancestors 'self'` is the modern, more flexible directive — supports multiple origins and full URL matching. X-Frame-Options (`DENY` or `SAMEORIGIN`) is the legacy header understood by older browsers. The grader treats `frame-ancestors` as the primary signal; X-Frame-Options as the fallback.
- What is COOP / COEP and do I need them? Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy work together to enable cross-origin isolation — required for high-resolution timers, SharedArrayBuffer, and stronger Spectre-class defenses. `COOP: same-origin` + `COEP: require-corp` is the strict pairing. Required if you use SharedArrayBuffer or want the strongest process isolation; otherwise nice-to-have.
- What is Permissions-Policy? Restricts which browser features (geolocation, camera, microphone, payment APIs, USB, accelerometer, etc) the page and embedded iframes can use. Modern replacement for Feature-Policy. Best practice: explicitly deny features you don't use — `Permissions-Policy: geolocation=(), camera=(), microphone=()`. Reduces attack surface from compromised third-party scripts.
- Why is my site graded lower than expected? Common causes: HSTS max-age too short (under 1 year), no CSP at all, CSP uses `'unsafe-inline'`, X-Frame-Options missing while no `frame-ancestors` directive present, Server header leaking detailed version info, missing Permissions-Policy. The per-header breakdown identifies the exact gap and the recommended fix value.