Home/Free tools/Security Headers Guide

Security Headers Guide

Paste a set of response headers for a graded review, then read what each header actually does and how to deploy a Content-Security-Policy without breaking things.

Runs entirely in your browser. Nothing you type here is transmitted, logged, or stored. There is no server to send it to. Open your developer tools and watch the network tab if you want to confirm it.

Get them with curl -sSI https://yourdomain.com, or copy the response headers from your browser's network tab. This page cannot fetch the site for you: there is no server here to make the request, which is the same reason nothing you paste can leave your browser.

Reference

What each header actually does

Ordered by how much difference it makes in practice, not alphabetically. The first two are worth real engineering time; the rest are configuration.

HeaderWhat it doesWhy it matters
Content-Security-PolicyDeclares which origins may supply script, style, frames and other content, and what inline code is allowed to run.The only header that limits what an injection bug can actually do. Also the only one that can break your site, which is why it is so often missing.
Strict-Transport-SecurityTells the browser to reach this host over HTTPS only, for a stated period.Closes the window where a first request over http:// can be intercepted and downgraded before your redirect runs.
X-Content-Type-Optionsnosniff stops the browser second-guessing your Content-Type.Prevents an uploaded file or a JSON endpoint being re-interpreted as script. One value, no compatibility risk.
CSP frame-ancestorsControls who may put your pages in a frame. Replaces X-Frame-Options.Without it, clickjacking is available against any state-changing UI you have: transfers, permission grants, deletions.
Referrer-PolicyDecides how much of the current URL is sent when a user navigates away.Password-reset and invitation URLs end up in third-party logs when this is left permissive.
Permissions-PolicySwitches off browser features (camera, microphone, geolocation) for your pages and anything embedded in them.Mostly a constraint on third-party frames you embed. Cheap to set, small payoff.
Cross-Origin-Opener-PolicySevers the window reference between your page and cross-origin windows.Blocks a class of cross-window attacks and enables cross-origin isolation. Check any OAuth popup flows before enabling.
Rollout

Deploying a CSP without breaking the application

Most teams that have no CSP tried once, broke something in production, and reverted. The report-only phase is what makes this safe, and it is the step usually skipped.

  • Start in report-only. Ship Content-Security-Policy-Report-Only with the policy you eventually want. It blocks nothing and reports everything, so production traffic tells you what would have broken.
  • Collect reports for a full business cycle. A fortnight catches the weekly batch job, the monthly invoice run, and the marketing tag someone adds on a Friday. A day catches your own testing.
  • Fix the violations, do not widen the policy. Every report is either a dependency you forgot about or inline code that should move to a file. Adding the offending origin to the allow-list is how policies decay into permitting everything.
  • Use nonces rather than 'unsafe-inline'. Generate a random nonce per response, put it on your own script tags and in the policy. Inline script injected by an attacker will not carry it.
  • Set base-uri and object-src. Without base-uri 'self' an injected <base> tag re-points every relative script URL at the attacker. It is the most commonly missed directive in an otherwise decent policy.
  • Enforce, then keep the report endpoint.Move the header to the enforcing name and leave reporting on. It is how you find out that last week's deploy is now silently blocked.
A reasonable starting policy
Content-Security-Policy-Report-Only:
  default-src 'self';
  script-src 'self' 'nonce-{RANDOM_PER_RESPONSE}';
  style-src 'self' 'nonce-{RANDOM_PER_RESPONSE}';
  img-src 'self' data:;
  connect-src 'self';
  frame-ancestors 'none';
  base-uri 'self';
  object-src 'none';
  form-action 'self';
  report-uri /csp-report

Tighten from here rather than loosening towards here. If a directive has to be relaxed, relax that one directive instead of falling back on default-src.

Cleanup

Headers still widely recommended that do nothing

These appear in most hardening checklists and a good number of compliance templates. They are no longer doing anything for you.

!

X-XSS-Protection

The browser auditor it configured has been removed from Chrome and Edge. While it existed it introduced its own bugs. Setting it to 1; mode=block achieves nothing today.

remove
!

Expect-CT

Deprecated. Certificate Transparency is enforced unconditionally by browsers now.

remove
!

Public-Key-Pins

Dead and ignored. When it worked, a pinning mistake took your domain offline until the pin expired, with no way to recover.

remove
!

Feature-Policy

Renamed to Permissions-Policy with slightly different syntax. Migrate the directives rather than shipping both.

remove
← All free tools