// HTTP

Security Headers Check

See which browser-side defences a site has switched on, and what each missing one costs.

We request the page once and read only its response headers. The body is never downloaded.

// Copy-paste configuration

The seven headers this tool scores, and what each one buys you. The blocks below set all of them and score 100 against this checker.

HeaderValueWhat it prevents
Strict-Transport-Securitymax-age=31536000; includeSubDomainsBrowsers refuse plain HTTP for this domain for a year after the first visit.
Content-Security-Policydefault-src 'self'; …Declares where scripts and other resources may load from, so injected script has nowhere to run.
X-Frame-OptionsDENYStops the page being framed by another site, which is what clickjacking needs.
X-Content-Type-OptionsnosniffStops a browser reinterpreting an upload as executable script.
Referrer-Policystrict-origin-when-cross-originKeeps full URLs, and anything sensitive in them, from leaking to third-party sites.
Permissions-Policycamera=(), microphone=(), geolocation=()Switches off powerful browser features for the page and anything it embeds.
Cross-Origin-Opener-Policysame-originIsolates the page from any cross-origin window that opened it.

nginx

Inside the server block, or in a snippet included from it.

# --- Security headers -------------------------------------------------
# 'always' matters: without it these are dropped on error responses,
# which is exactly when a browser most needs them.

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" 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;
add_header Cross-Origin-Opener-Policy "same-origin" always;

# Start with Content-Security-Policy-Report-Only, then rename to enforce.
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; object-src 'none'" always;

# Stop advertising the software version.
server_tokens off;

// Before you paste this

  • add_header does not inherit into a nested location block that declares its own add_header. If you set headers anywhere else in the config, repeat the whole set there or move them into an included snippet.
  • server_tokens off shortens the Server header to nginx but does not remove it. Removing it entirely needs the headers-more module: more_clear_headers Server;
  • Do not add preload until you are certain every subdomain serves HTTPS. Preloading is baked into browser binaries and removal takes months.
  • The Content-Security-Policy line is a starting point, not a drop-in. If your site uses inline scripts, inline styles or third-party widgets, this policy will block them. Deploy it as Content-Security-Policy-Report-Only first, watch the reports for a week, then switch the header name to the enforcing version.

// What HTTP security headers actually do

When a server answers a request it sends headers alongside the content. A handful of them are safety instructions: insist on HTTPS from now on, restrict where scripts may load from, refuse to be embedded in someone else's page, stop guessing at content types. None of them cost anything to send, and each one removes a category of attack that would otherwise be available.

Strict-Transport-Security is the highest-value of the set. It tells the browser to refuse plain HTTP for this domain for a fixed period, closing the window in which a first request over HTTP can be intercepted and redirected somewhere else. Six months is the usual minimum, because the header is worth very little with a short max-age.

Content-Security-Policy is the most powerful and the most work. It declares where scripts, styles, images and connections may come from, so that injected script has nowhere to run from. It is also the header most likely to break a working site, which is why it is normally deployed in report-only mode first and tightened once the reports go quiet. A policy containing 'unsafe-inline' still helps, but it gives up most of the protection against cross-site scripting.

The rest are one-liners. X-Frame-Options, or CSP frame-ancestors, stops clickjacking. X-Content-Type-Options: nosniff stops a browser reinterpreting an uploaded file as executable script. Referrer-Policy stops full URLs, including anything sensitive sitting in a query string, being handed to third-party sites when someone clicks away. Permissions-Policy switches off camera, microphone and geolocation for anything you embed.

A grade here measures configuration, not safety. A site with perfect headers can still have an injection bug, and a site with none may be carefully written. What the grade tells you is how much cheap defence-in-depth is currently sitting on the table unclaimed.

// MethodologyWhat this tool tests, which sources it uses, and where it stops being reliable.

// Frequently asked questions

Will adding a Content-Security-Policy break my site?
It can, if you rely on inline scripts or third-party widgets. Deploy it as Content-Security-Policy-Report-Only first, watch what gets reported for a week or two, then switch to enforcing once the reports are clean.
Which header should I add first?
Strict-Transport-Security and X-Content-Type-Options. Both are a single line, neither breaks anything, and together they close off protocol-downgrade attacks and MIME confusion. Add X-Frame-Options next, then work up to a CSP.
Do security headers help SEO?
Not directly. Serving over HTTPS is a ranking signal; the headers themselves are not. They matter for user safety and for passing security reviews, not for rankings.
Why does my site score badly when it is behind a CDN?
Most CDNs and hosting platforms pass through whatever your origin sends and add nothing of their own. Cloudflare, Vercel, Netlify and the rest all let you set these headers in configuration. The defaults simply are not set for you.
Is it safe to run this against a site I do not own?
Yes. It makes one ordinary GET request and reads the response headers, exactly as a browser would, and never downloads the page body. It does not scan ports, probe for vulnerabilities or submit anything.

// Related tools

// Part ofWebsite Security Tools