Security headers are the cheapest security control on the internet, and the
most commonly missing. On almost every scan we run, a missing
X-Content-Type-Options shows up before anything more interesting — because
it's pure configuration, the thing AI models are least likely to write for
you.
The good news: it's a 10-minute fix, and once it's done it's done. Here's exactly what to ship.
#The high-impact five
You don't need a dozen headers. You need these five, which together stop the most common browser-side attacks:
| Header | What it does | Attack it stops |
|---|---|---|
Content-Security-Policy | Restricts what resources the page may load | XSS, injection, data exfiltration |
Strict-Transport-Security | Forces HTTPS for a period | SSL strip, downgrade attacks |
X-Content-Type-Options: nosniff | Blocks MIME-type sniffing | Malware via mislabeled uploads |
Referrer-Policy | Limits what URLs leak in the Referer header | Information disclosure |
Permissions-Policy | Disables unused browser features (camera, mic, geolocation) | API abuse, fingerprinting |
#Where to set them (and where not to)
The number one mistake AI-generated code makes is putting headers in the
wrong layer. Setting Content-Security-Policy in your index.html meta tag
is the least effective place: it can't set HSTS, can't send the
frame-ancestors directive reliably, and applies late in the response path.
Headers belong at the edge:
- Vercel / Netlify —
vercel.json/netlify.tomlheadersblocks - Cloudflare / other CDNs — Transform Rules or edge functions
- Nginx / Caddy — server block
add_header/headerdirectives
Example for a static site on Vercel:
{
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "Strict-Transport-Security", "value": "max-age=63072000; includeSubDomains" },
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
{ "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" }
]
}
]
}
CSP needs more thought (see below), so it's left out of the safe-by-default set above.
#CSP without the pain
Content-Security-Policy is the most powerful header and the one most
likely to break things. The pragmatic path for a modern app:
default-src 'self';
script-src 'self' 'unsafe-inline' https://cdn.example.com;
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
connect-src 'self' https://api.vergate.dev;
frame-ancestors 'none';
Two rules of thumb:
- Ship report-only first. Use
Content-Security-Policy-Report-Onlywith areport-toendpoint, watch violations for a week, then flip to enforcing. This is the single highest-value habit in header deployment. - Don't paste a template blindly. If you use inline event handlers or eval (many AI-generated scripts do), a strict template CSP will break your app at 3am. Either fix the code or scope the CSP to your actual needs — but close the obvious holes.
#What a scan should show
When you scan your site, the header check passes when all five are present and sane. A clean result looks like:
Content-Security-Policy ✓ present
Strict-Transport-Security ✓ present (max-age >= 6 months)
X-Content-Type-Options ✓ nosniff
Referrer-Policy ✓ strict-origin-when-cross-origin
Permissions-Policy ✓ present
That's a pass you can ship with. It's also the kind of check that, once green, stays green — until someone rebuilds the edge config from scratch and silently drops them all. That's why it's worth adding headers to your launch checklist, right next to scanning before you ship.
#The rest of the story
Headers are defense-in-depth, not a shield. They stop the browser-side attacks; they don't stop a leaked API key or an unvalidated login form. Use the OWASP Secure Headers Project as your reference, and pair headers with the rest of the vibe coding security baseline — secrets hygiene, input validation, and least-privilege keys.
Set the five headers, verify them with a scan, and move on. It's ten minutes that will show up as a green check on every security report you ever run again.
Frequently asked questions
Which security headers are actually important?
The high-impact five are: Content-Security-Policy, Strict-Transport-Security (HSTS), X-Content-Type-Options, Referrer-Policy, and Permissions-Policy. They stop the most common browser-side attacks — XSS, MIME sniffing, clickjacking, and data leaks via referrer.
Why does AI-generated code miss security headers?
Security headers are infrastructure, not feature code. LLMs are trained mostly on application code and rarely on deployment configuration, so they add a CSP to your index.html but not your edge config — which is where it actually belongs.
Will security headers break my site?
CSP can break inline scripts and third-party embeds if it's too strict. Ship it in report-only mode first (Content-Security-Policy-Report-Only), watch for violations, then enforce. The other four headers are safe to turn on immediately.