WhoopsBot

Guides · Updated 2026-10-23

Which security headers a small web app should send

What HSTS, Content-Security-Policy, nosniff, frame protection, Referrer-Policy, and Permissions-Policy do, and what a missing header does not prove.

A header is a promise about the response

Security headers are instructions the browser applies to a response. They do not patch a bug in your signup handler, and they do not hide a secret you already shipped in JavaScript. They do limit a few common ways a response gets abused: being framed, being sniffed as a different type, leaking a full URL to the next site, or loading scripts you did not name.

The free security-headers check looks at one page and lists which of six headers are absent. It does not score how strict a policy is. A Content-Security-Policy of default-src * is present, so the check will not call it missing, and it is still loose. Read the absence list as a to-do, not as a grade of the whole app.

The six the check looks for

Strict-Transport-Security tells a browser to keep using HTTPS for this host. The check only expects it when the final URL is HTTPS. Sending it on a broken HTTPS setup can pin people to a host they cannot reach, so turn it on after HTTPS works, and start with a modest max-age if you are unsure.

Content-Security-Policy lists where scripts, frames, and other resources may come from. It is the header that stops a lot of injected script, and it is also the header that breaks Stripe.js, Paddle.js, and analytics when you forget their hosts. Add the hosts you actually use. Do not copy a policy from another product and hope.

X-Content-Type-Options: nosniff tells the browser not to sniff a file into a different type. The check looks for that exact value. A different value counts as missing.

Clickjacking protection is either X-Frame-Options or a frame-ancestors directive in the Content-Security-Policy. One of them is enough for the check. SAMEORIGIN is a reasonable start if you do not embed your own pages in other sites. DENY is stricter. If a partner embeds you, frame-ancestors is the precise tool.

Referrer-Policy controls how much of the current URL is sent when someone leaves. strict-origin-when-cross-origin is a solid default: same-origin navigations can send the path, and other sites get the origin only, and only on HTTPS.

Permissions-Policy turns off browser features you do not use. If the product does not need camera, microphone, or location, say so. A page that does use one of them should allow it for that page only, not for every embedded frame.

Where to set them

Set the headers on the response that serves HTML, at the host or the framework, so every document gets them. A header that exists only on a single API route does not protect the page. A header set in a meta tag is not a substitute for the ones that must be real headers. Content-Security-Policy and HSTS belong on the response.

Check the published origin, including www if that host also answers. A header on the apex and not on www is a split configuration. After you deploy, request the page again. A CDN can cache the old headers until its TTL passes.

What not to panic about

Missing headers are a warning on the free check, not a statement that the database is public. An exposed service role key, a public /.env, or a public /.git directory is a different severity. Fix those first if they show up in the same report. The headers page will still be there after you rotate the key.

Do not add a strict Content-Security-Policy in one step on a Friday. Start by sending the headers that rarely break a page: nosniff, a frame policy, a referrer policy, and a permissions policy that matches what you use. Add HSTS once HTTPS is stable. Add a Content-Security-Policy in report-only mode if you can, read what it would have blocked, then enforce it. Checkout buttons are a common casualty. Confirm Stripe or Paddle still opens before you call it done.

If a header is set twice, browsers generally use the first Content-Security-Policy they understand and can get confused by duplicates. One place should own the list: the framework, the proxy, or the host, not all three with different values. When the tool says a header is missing, view the response on the published URL, not the value you remember typing into a file that this deploy did not use.

How to recheck

Paste the URL into the security headers tool. It runs the same one-page check as the homepage, and the report names the headers it did not see. It also includes the rest of that check: load, console, broken images and links, obvious tokens, and the /.env and /.git probes. It does not crawl the site or log in.

Headers do not need an hourly browser. They change when you change the host config. Recheck after a deploy that touched the server, the proxy, or the framework headers. A saved flow is for the click path, not for this list.

Questions

Does a passing header check mean the Content-Security-Policy is strict?

No. The check reports headers that are missing. A present policy can still allow more than you wanted.

Is HSTS required on an http-only site?

No. The check looks for Strict-Transport-Security when the final URL is HTTPS.

Related

Check the published page.

No card needed. Free plan forever. Cancel anytime.