5 Security Headers Every Vibe-Coded App Needs
Most AI-generated apps ship with zero security headers. Here are the five headers every app needs — CSP, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy — with copy-paste Next.js and Express code.

Last month, a developer I know launched his SaaS. Three days later, he got a panicked DM from a user: "Why is your app asking me to re-enter my credit card?" He opened the link. It looked exactly like his app — same logo, same layout, same login screen. But it wasn't his domain. Someone had embedded his entire application inside an invisible iframe on a phishing page, and his users were handing over their credentials without realizing it.
The fix took ten minutes. Five lines of configuration. Headers he'd never heard of.
When VibeShield scans an AI-generated app, missing security headers are one of the most common findings. Out of over 20,000 vibe-coded apps analyzed, the majority shipped with zero security headers configured. Not "wrong" headers — zero. These aren't obscure edge cases. They're the seatbelts of the web, and your AI coding tool didn't install any of them.
Here are the five headers that would have saved my friend's app — and the copy-paste code to add them to yours right now.
1. Content-Security-Policy (CSP)
CSP tells the browser which sources of content are allowed to load and execute. If an attacker injects a malicious script through an XSS vulnerability, CSP can block it from running entirely.
Think of CSP as a bouncer at the door of your app. Every script, stylesheet, image, and font has to show ID. If the bouncer doesn't recognize the source, it doesn't get in.
// next.config.ts
async headers() {
return [{
source: '/(.*)',
headers: [{
key: 'Content-Security-Policy',
value: "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'"
}]
}];
}Figure 2: Next.js CSP configuration — blocks unapproved scripts, styles, images, fonts, and connections.
Pro tip: Start with Content-Security-Policy-Report-Only first. Load your app, check the browser console for violations, fix them, then switch to the enforcing header. Nobody gets CSP right on the first try — report-only mode is your safety net.
2. Strict-Transport-Security (HSTS)
HSTS tells the browser: "Never talk to me over HTTP. Only HTTPS. Ever."
Without HSTS, even if your server redirects HTTP to HTTPS, that first unencrypted request is a window. An attacker on the same coffee shop Wi-Fi can intercept it before the redirect happens and serve a fake version of your site.
Strict-Transport-Security: max-age=63072000; includeSubDomains; preloadFigure 3: HSTS header — tells the browser to only use HTTPS for the next two years, including subdomains.
max-age=63072000 means two years. Set it long. includeSubDomains covers app.yoursite.com and api.yoursite.com. preload lets you submit to browser HSTS preload lists — then users are protected before they even visit your site for the first time.
3. X-Frame-Options
This is the header my friend needed. It controls whether your site can be embedded in an iframe on another domain.
Without X-Frame-Options, an attacker can load your app in an invisible iframe, overlay transparent buttons on top of yours, and trick users into clicking things they can't see. It's called clickjacking, and it's been around for over a decade. AI coding tools still don't add this header.
X-Frame-Options: DENYFigure 4: X-Frame-Options — DENY blocks all iframe embedding, preventing clickjacking attacks.
DENY blocks all framing. SAMEORIGIN allows framing only by your own domain. Unless you specifically need iframe embeds, use DENY. CSP's frame-ancestors 'none' directive is the modern equivalent — deploy both for maximum browser coverage.
4. X-Content-Type-Options
Browsers are helpful. Sometimes too helpful. When a server says "this is a text file" but the content looks like JavaScript, the browser might "sniff" the MIME type and execute it anyway. Attackers exploit this by uploading files that look like images but contain executable code.
X-Content-Type-Options: nosniffFigure 5: X-Content-Type-Options — prevents MIME sniffing, forcing the browser to respect the server's Content-Type.
One line. It tells the browser to trust the server's Content-Type header — no guessing, no sniffing. If your server says it's an image, the browser treats it as an image. Period.
5. Referrer-Policy
When a user clicks a link from your site to another, the browser sends a Referer header telling the destination where the user came from. If that URL contains sensitive data — session tokens in query parameters, internal paths, user IDs — you're leaking information to every site you link to.
Referrer-Policy: strict-origin-when-cross-originFigure 6: Referrer-Policy — sends only the origin to external sites, protecting internal URLs and query parameters.
This policy sends the full referrer within your own site (useful for analytics) but only the origin when navigating to external sites (no path, no query parameters). It's the best balance of privacy and utility.
Header Impact Comparison
Not all missing headers are equally dangerous. Here's what each one actually protects against:
| Header | Protects Against | Risk If Missing | Implementation Difficulty |
|---|---|---|---|
| Content-Security-Policy | XSS, data injection, clickjacking | Critical — any XSS vector becomes exploitable | Medium — requires testing with report-only |
| Strict-Transport-Security | Man-in-the-middle, SSL stripping | High — users on public Wi-Fi are exposed | Low — one line |
| X-Frame-Options | Clickjacking, UI redress | High — entire app can be invisibly framed | Low — one line |
| X-Content-Type-Options | MIME sniffing attacks | Medium — depends on upload features | Low — one line |
| Referrer-Policy | Information leakage via URLs | Low — leaks internal URLs to third parties | Low — one line |
Figure 1: Security headers ranked by protection scope, risk severity, and implementation effort.
Express: All Five in One Line
If you're on Express, Helmet handles everything:
const helmet = require('helmet');
app.use(helmet());Figure 7: Helmet in Express — one line adds five security headers plus several more.
That's it. Five headers plus several more. For CSP customization:
app.use(helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
connectSrc: ["'self'"],
frameAncestors: ["'none'"],
}
}));Figure 8: Custom CSP via Helmet — allows specifying exact directives for each content type.
The Result
Before adding headers: VibeShield shows red across the board. After: green checks, your app has production-grade header security. The fix is usually a single configuration change — a middleware file, a next.config.ts update, or one app.use(helmet()) call.
Ten minutes. That's the difference between your app and the one my friend almost lost his business over.
Summary
- The five essential security headers are CSP (blocks injected scripts), HSTS (enforces HTTPS), X-Frame-Options (prevents clickjacking), X-Content-Type-Options (stops MIME sniffing), and Referrer-Policy (prevents URL leakage). Most AI-generated apps ship with zero of these.
- CSP is the most impactful but hardest to configure — start with
Content-Security-Policy-Report-Onlyand monitor violations before switching to enforcement. Nobody gets CSP right on the first try. - Implementation is usually a single config change: a Next.js middleware file, a
next.config.tsupdate, or oneapp.use(helmet())call in Express. Ten minutes is all it takes. - The risk scales with what's missing: no CSP means any XSS vector is exploitable, no HSTS means public Wi-Fi users are exposed to MITM, no X-Frame-Options means your entire app can be invisibly framed for phishing.
Found this useful? Scan your app at vibeshield.org — we'll tell you exactly which headers are missing and how to fix them.
Read next: Cookie Security: Your Session Token Is One Flag Away from Theft — headers protect your app, but cookie flags protect your users' sessions. Also The Header Your AI App Is Missing (And Why It Matters) for a deep dive into building a CSP that actually works.