Missing security headers: check HSTS, CSP, X-Frame-Options and nosniff
A scanner says a security header is not set? Check all four at once: HSTS, Content-Security-Policy, X-Frame-Options and X-Content-Type-Options, then fix each one on your host.
Short answer
Security scanners commonly flag four response headers: Strict-Transport-Security (HSTS), Content-Security-Policy, X-Frame-Options and X-Content-Type-Options. Open the live page's response headers and see which are missing. Send HSTS only over HTTPS, for example max-age=31536000; includeSubDomains. Then add each missing header where your host sets response headers, such as vercel.json on Vercel or a _headers file on Netlify.
Reviewed October 28, 2026
The checklist
Check each header in the live document response, then follow the fix for any that are missing.
| Header | What it does | Fix |
|---|---|---|
Strict-Transport-Security (HSTS) |
Tells the browser to use HTTPS for the host from then on | Covered on this page |
Content-Security-Policy (CSP) |
Limits where the page may load scripts and other resources from | Content Security Policy header not set |
X-Frame-Options |
Stops other sites putting your page in a frame | X-Frame-Options header not set |
X-Content-Type-Options |
Turns off MIME type sniffing with nosniff |
X-Content-Type-Options header missing |
What it means in plain English
These four response headers tell the browser how to treat your page:
- Content-Security-Policy limits which scripts and other resources the page may load. MDN describes it as a defense against injected scripts.
- Strict-Transport-Security (HSTS) tells the browser to use HTTPS for that host from then on. MDN says browsers ignore this header when it arrives over plain HTTP.
- X-Frame-Options tells the browser not to put your page inside another site's frame. MDN says that without this header, and without a CSP
frame-ancestorsrule, other sites may embed the page. - X-Content-Type-Options: nosniff tells the browser to trust the declared
Content-Typeinstead of guessing it.
These have to be HTTP response headers. MDN says an X-Frame-Options meta tag has no effect. A CSP meta tag does not support every CSP feature.
Likely causes
- The AI-built app is a static site, and the host was never told to add headers.
- HSTS was added on an
http://response, so the browser ignored it. - The frame protection was put in a
<meta>tag instead of the response.
HSTS (Strict-Transport-Security)
MDN says "the host must send the Strict-Transport-Security header over HTTPS only, not insecure HTTP," and browsers ignore it if it is sent over HTTP. MDN's example:
Strict-Transport-Security: max-age=31536000; includeSubDomains
If the host accepts plain HTTP requests, MDN says it should answer with a permanent redirect to HTTPS, and that redirect must not include the header. To join the separate preload list, MDN says max-age must be at least 31536000 (one year) and includeSubDomains must be present.
How to fix it, step by step
- Open the live page, then the browser's network panel, and read the response headers for the document. Tick off the four headers in the checklist above.
- Send HSTS only on an HTTPS response, as described in the HSTS section above.
- Send
X-Frame-Options: DENYorX-Frame-Options: SAMEORIGIN. MDN also points at CSPframe-ancestorswhen you need a finer rule than those two. See X-Frame-Options header not set. - Send
Content-Security-Policyas a response header. MDN's small example isdefault-src 'self'. That blocks scripts from other sites, so a page that loads a chat widget or analytics from another host will need those hosts named in the policy. See Content Security Policy header not set. - Send
X-Content-Type-Options: nosniffon every path, and check that scripts and stylesheets are served with the rightContent-Type. See X-Content-Type-Options header missing. - Put the headers where the host attaches response headers, such as the
headerslist invercel.jsonon Vercel or a_headersfile on Netlify, then redeploy. Check the document response again, not the HTML source.
How to check it worked
- The document response includes all four headers.
- The page still loads the scripts it needs. If a script is blocked, the console names the CSP rule. Adjust the policy, don't delete it.
Questions people ask
Which security headers do scanners usually flag as missing?
This checklist covers the four that are commonly flagged: Strict-Transport-Security, Content-Security-Policy, X-Frame-Options and X-Content-Type-Options. Each one is a separate HTTP response header, so each needs its own fix.
Why is my HSTS header ignored?
MDN says browsers ignore Strict-Transport-Security when it arrives over plain HTTP. Send it only on HTTPS responses, and redirect HTTP requests to HTTPS without the header.
Can I add security headers with a meta tag?
Not all of them. MDN says an X-Frame-Options meta tag has no effect, and a CSP meta tag does not support every CSP feature, such as frame-ancestors. Send them as response headers.
Sources
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP (opens in a new tab)
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Strict-Transport-Security (opens in a new tab)
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Frame-Options (opens in a new tab)
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Content-Type-Options (opens in a new tab)
- https://vercel.com/docs/project-configuration/vercel-json (opens in a new tab)
- https://docs.netlify.com/manage/routing/headers/ (opens in a new tab)
Related fixes
More Secret keys in the browser fixes
Keep going on your own.
The guides stay free. A deep leak report is $15. Fix packs are $24, or $49 for all three. There is no done-for-you repair.