How to fix a missing Content-Security-Policy header
Your site is missing a Content-Security-Policy (CSP) header. CSP tells the browser which scripts, styles, and images are allowed to load, blocking malicious injections like XSS. Without it, a single vulnerable dependency or user input field can be used to steal sessions, redirect users, or deface your app. The fix is to send a CSP header from your hosting platform or framework — one line in Next.js config or a vercel.json rule. Start with a permissive policy in report-only mode, then tighten it.
Why it matters
XSS is the single most common web vulnerability. CSP is the browser-level backstop that stops XSS even when your code has a bug. AI-generated apps often paste user input directly into pages, which makes CSP the cheapest defense you can ship.
How to check
- 01Open your site in Chrome, then open DevTools → Network tab.
- 02Reload the page and click the first (document) request.
- 03Under Response Headers, look for `content-security-policy`.
- 04If it is missing or set to `default-src *`, the header is not protecting you.
Or let SafeToShip check it for you in 60 seconds:
How to fix it
Next.js (next.config.js)
Add a headers() function that applies a baseline CSP to all routes. Tighten allowed origins as you identify them.
module.exports = {
async headers() {
return [{
source: '/:path*',
headers: [{
key: 'Content-Security-Policy',
value: "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https://*.supabase.co https://api.stripe.com; frame-ancestors 'none';"
}]
}];
}
};Vercel (vercel.json)
If you deploy to Vercel without a framework, add a headers rule in vercel.json.
{
"headers": [{
"source": "/(.*)",
"headers": [{
"key": "Content-Security-Policy",
"value": "default-src 'self'; script-src 'self' 'unsafe-inline'; frame-ancestors 'none';"
}]
}]
}Generic (any host)
Send this response header from your CDN, reverse proxy, or server. Cloudflare, Netlify, and Fastly all have header-injection settings.
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; frame-ancestors 'none'AI prompt
Copy-paste into your AI tool
Paste this prompt into Cursor, Lovable, Bolt, v0, or Claude Code and it will walk through the fix for your specific codebase.
Add a baseline Content-Security-Policy header to my app. It should apply to every route. Allow scripts and styles from the same origin plus any CDNs I am already loading (check my code for <script src="..."> and <link href="..."> tags). Allow images from https: and data: URIs. Block framing with frame-ancestors 'none'. Allow API calls to any Supabase, Stripe, or third-party domain I am already calling from client code. Return the exact code change needed for my framework and paste the final header value so I can verify it in DevTools.FAQ
Frequently asked questions
- Will CSP break my site?
- It can, if you load scripts from a domain the policy does not allow. Start in report-only mode by sending `Content-Security-Policy-Report-Only` instead of `Content-Security-Policy`. The browser will log violations without blocking them. Watch the console for a week, then switch to enforcing mode.
- Should I use 'unsafe-inline' or a nonce?
- Nonces are stronger but harder to set up. If you are shipping fast, `'unsafe-inline'` for scripts and styles is acceptable as a starting point. Graduate to nonces once you are tracking down any inline scripts your framework generates.
- Does Next.js have CSP built in?
- Not automatically. Next 13+ supports nonces via middleware, but you still have to opt in. The fastest path is the `headers()` config above. Vercel-hosted Next.js apps can also set headers in `vercel.json`.
Related fix guides
Fix these too
Missing X-Frame-Options
Without X-Frame-Options or CSP frame-ancestors, attackers can embed your site in an invisible iframe to trick users into clicking things. Here is the fix.
Read moreMissing HSTS header
HSTS tells browsers to always use HTTPS for your site. Without it, users can be downgraded to HTTP and have sessions stolen. Here is how to add HSTS on Vercel, Next.js, and other hosts.
Read moreMissing Permissions-Policy
Permissions-Policy controls which browser features (camera, microphone, geolocation) your site and its iframes can use. Default-allow is unsafe — lock it down.
Read moreLearn the concepts
Glossary
Content Security Policy
CSP is a browser feature that tells your site which scripts, styles, and images are allowed to run. It is the main defense against cross-site scripting (XSS).
Read moreCross-Site Scripting
XSS is an attack where malicious JavaScript gets injected into your site and runs in other users' browsers. CSP and input sanitization are the main defenses.
Read moreSecurity Headers
A set of HTTP response headers that harden your site against common web attacks. Every site should send all six.
Read moreFree tools
Check this yourself
Platform guides
Building on these platforms?
Next.js security
Next.js is the most popular React framework, but even experienced developers miss security headers and accidentally expose server files in production.
Read moreVercel security
Vercel handles hosting and SSL, but your application code still needs security hardening. Missing CSP headers and exposed environment variables are the top issues.
Read moreLovable security
Lovable makes it easy to ship fast, but AI-generated backends often ship with open Supabase tables and leaked API keys. Scan your Lovable app before your users find out.
Read morev0 security
v0 generates beautiful React components, but when you connect a backend, security gaps appear. Missing CSP headers and insecure cookie settings are the most common.
Read moreScan your site for this and 50+ other issues
Free scan. Results in 60 seconds. No account required.