Security headers checker for websites

Enter a domain. SetEnforce requests its HTTPS front page once and checks the response headers that tell browsers how to treat the site: HSTS, Content-Security-Policy, frame protection, Referrer-Policy and more.

The bare domain, without http:// or a path.

Single-standard checks this hour Loading...

Anonymous results are kept for 1 hour. Single-standard check

This check runs Web security only, not the other 13 standards. No account needed: 20 single-standard checks an hour, separate from the 5 full scans a day. A result reused from the last 5 minutes is free.

How the security headers check works

A response header is an instruction to the browser. The check reads what your server sends and judges whether each instruction does its job.

  1. Request the front page

    The scan sends one HTTPS GET to the domain and follows redirects. The headers on the final response are the ones judged. No login, no account and no domain verification are involved.

  2. Read each header

    Strict-Transport-Security, Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy and the Cross-Origin family (COOP, COEP, CORP) are looked up on that response. A header that is absent is a control that is absent.

  3. Judge the policy, not just the header

    A Strict-Transport-Security header with a short lifetime, or a Content-Security-Policy that allows unsafe-inline scripts, is present and still protects little. The policy checks grade the lifetime, the subdomain coverage and what the CSP actually blocks.

  4. Check the way in

    Two checks look at how a visitor arrives: whether plain HTTP upgrades to HTTPS in one hop without changing host, and whether every reachable host variant carries the same protections.

  5. Add the transport underneath

    The web security standard also covers the certificate, the TLS versions and cipher suites, cookies and mixed content. This free check shows the certificate, TLS and the main header results; the findings list with every check is part of a signed-in full scan.

Scope and limits

  • One URL: the front page at https://<domain>. Headers on other paths and on other subdomains can differ.
  • Passive at the free tier. CORS origin reflection and TLS 1.3 early data need active probing and are reported as not tested.
  • security.txt is a separate standard with its own two checks. It runs in a full scan, not in this check.
  • No letter grade. Every check has its own status and severity, with the evidence behind it.

What each header does

Short version of what the checks look for. The remediation text in a full scan has the exact values.

Strict-Transport-Security
Tells the browser to use HTTPS for the domain for a stated time. Without it, the first request after a user types the bare hostname is cleartext. The strength check wants a long lifetime and includeSubDomains.
Content-Security-Policy
Limits where a page may load script from and send data to, so injected script has less to work with. A policy that allows unsafe-inline in script-src blocks nothing.
X-Frame-Options and frame-ancestors
Stop other sites from loading yours in an invisible frame to trick a signed-in user into clicking. Sending both covers old and current browsers.
X-Content-Type-Options
The only correct value is nosniff. It stops a browser from re-interpreting a response as script or stylesheet regardless of its declared type.
Referrer-Policy
Decides how much of the page URL is sent to other origins. Paths and query strings can carry reset tokens and internal identifiers.
Permissions-Policy
A deny list for browser features the site does not use, such as camera, microphone and geolocation, including for frames the page embeds.
Cross-Origin-Opener-Policy
Cuts the link between your page and a cross-origin window that opened it, which several cross-window leak techniques depend on.
Cross-Origin-Embedder-Policy and Cross-Origin-Resource-Policy
Worth setting if the site needs cross-origin isolation. COEP can break third-party embeds that send no CORP or CORS headers, so the check reports a missing one as Info.

What a failing result looks like

Two common findings, in the words a full scan's report uses. The first is a site that sends no Content-Security-Policy. The second is one that can be loaded in a frame by any other site.

Medium A Content-Security-Policy header is present web.headers.content_security_policy

FailNo Content-Security-Policy header is sent.

Impact

Injected script runs with the page's full authority: it can read the DOM, exfiltrate session data and rewrite the page, with nothing to constrain where it may load code from or send data to.

Remediation

Send a Content-Security-Policy header on every HTML response. Start in report-only mode to find breakage:
  Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' 'nonce-<random-per-response>'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; report-uri /csp-report
Review reports, then switch the header name to Content-Security-Policy. Use a per-response nonce rather than 'unsafe-inline'; a policy allowing 'unsafe-inline' in script-src blocks nothing.
Medium Framing by unrelated origins is refused web.headers.frame_options

FailNo X-Frame-Options header is sent.

Impact

Any site can load this one in an invisible frame and trick a logged-in user into clicking controls they cannot see, using their own authenticated session.

Remediation

Send both, so old and current browsers are covered:
  Content-Security-Policy: frame-ancestors 'self'
  X-Frame-Options: SAMEORIGIN
Use frame-ancestors 'none' and X-Frame-Options: DENY if the site is never framed. If specific partners must frame it, name them in frame-ancestors rather than dropping the header.

The certificate, TLS and main header results are part of every result, including this free check. The findings list with this impact and remediation text is part of the report of a signed-in full scan, which also covers the other standards.

How to fix a failing result

Do these in order. Each step is safe to ship on its own, except the Content-Security-Policy, which needs a trial run.

  1. Make HTTPS the only way in

    Redirect HTTP to HTTPS on the same host, then send Strict-Transport-Security: max-age=31536000; includeSubDomains. Roll it out in stages: start at max-age=300, confirm no subdomain still needs HTTP, then raise it to a year. Submit to a preload list only once the year-long policy has been stable.

  2. Add the three cheap headers

    X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, and frame protection with Content-Security-Policy: frame-ancestors 'self' next to X-Frame-Options: SAMEORIGIN. They rarely break anything.

  3. Trial a Content-Security-Policy in report-only mode

    Send Content-Security-Policy-Report-Only first, collect the reports, fix what would break, then switch to the enforcing header. Use a per-response nonce for scripts, not unsafe-inline.

  4. Deny the browser features you do not use

    Send Permissions-Policy: geolocation=(), camera=(), microphone=(), payment=(), interest-cohort=() and Cross-Origin-Opener-Policy: same-origin. Use same-origin-allow-popups only if the site opens windows it must keep a handle on.

  5. Set the cross-origin isolation pair only if you need it

    Cross-Origin-Embedder-Policy: require-corp breaks third-party embeds that send no CORP or CORS headers, so trial it with the report-only header. Cross-Origin-Resource-Policy: same-origin fits resources that should not be embedded elsewhere.

  6. Check again

    Run the check once the new headers are live. Check the host people really use, and the other host variant, since each can be configured separately.

Headers are one part of a full scan

A full scan runs 14 standards and 110+ checks: DNSSEC, DANE, RPKI, SPF, DKIM and DMARC, MTA-STS, CAA, registration, security.txt, TLS and the web headers on this page. It maps the results to NIS2, ISO 27001 and BSI IT-Grundschutz and gives each failing check its impact and fix.

Coming from the securityheaders.com API, which Snyk has discontinued? This page is the browser check. To script the same check, the API docs have a migration guide with the exact calls.

Run a full scan API migration guide

Frequently asked questions

Which headers does the checker look at?
Strict-Transport-Security, Content-Security-Policy, X-Frame-Options and CSP frame-ancestors, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, Cross-Origin-Opener-Policy, Cross-Origin-Embedder-Policy and Cross-Origin-Resource-Policy. It also judges the policy, not only whether the header exists: an HSTS lifetime that is too short, or a CSP that allows unsafe-inline scripts, is reported.
Does it give a letter grade?
No. Each check passes, partly passes or fails, and a failure carries a severity from Info to High. A full scan reports each check with the evidence it saw and the fix, instead of squeezing the headers into one letter.
Why does a headers check also report the certificate and TLS versions?
Because it runs the whole web security standard, which covers the served certificate, TLS versions and cipher suites, cookies and mixed content next to the headers. A header sent over a connection that can be downgraded protects little, so the page shows them together.
Is every missing header a vulnerability?
No, and the severities say so. A missing Cross-Origin-Embedder-Policy is Info: it only matters if the site needs cross-origin isolation, and it can break third-party embeds. A missing HSTS or Content-Security-Policy header is Medium, and a weak HSTS policy is High.
Does it check security.txt?
Not in this check. security.txt is its own standard in a full scan, with two checks: one that the file is published at the well-known location, one that it is complete and unexpired.
Which URL does it test?
The front page at https://<your domain>, following redirects, once. Other paths and subdomains can send different headers. A full scan also compares the host variants it can reach, so a www or apex host that lacks the protections shows up.
Is the check passive?
At the free tier, yes: one ordinary HTTPS request plus a TLS handshake, no attack traffic. Two checks in the web security standard need active probing, CORS origin reflection and TLS 1.3 early data, and are reported as not tested at that depth.
Can I run it from a script?
Yes. Start a scan with "standards": ["web_security"] through the API, poll until it finishes and read the findings. The scan is asynchronous, so it is not a single request. The steps and a polling helper are in the API docs. Read the API migration guide.
Do I need an account?
No. Without an account you can run 20 single-standard checks an hour, separate from the 5 full scans a day, and a result reused from the last 5 minutes is free. Results are kept for 1 hour. This page checks web security only: the findings list with each check's severity and the full remediation text is part of a signed-in full scan.

Scan a domain

Keep reading

Other checkers

  • RPKI checkerWhich of a domain's nameserver and mail server prefixes are covered by a valid ROA.
  • DANE and TLSA checkerWhether every mail server publishes TLSA records that match its certificate.

On this site

  • Compliance benchmarkAnonymous, aggregate adoption rates for each standard across scanned domains.
  • FAQScan limits, result retention, passive and active scans.
  • Single-standard checksCheck RPKI, DANE, DNSSEC, email security or web security on its own.
  • Full domain scanAll 14 standards and 110+ checks in one report.

Knowledge base