All guides
High severitySecurity Headers

Content-Security-Policy (CSP): what it is and how to add one

Content-Security-Policy (CSP) is an HTTP response header that tells the browser which sources of script, style, and other content it is allowed to load and execute. A good CSP is one of the strongest defenses against cross-site scripting (XSS).

What it is

CSP is a browser-enforced allowlist. When your server sends a Content-Security-Policy header, the browser refuses to load or execute anything that the policy doesn't explicitly permit — inline scripts, third-party domains, eval(), and so on.

A policy is a list of directives. For example, script-src 'self' says "only run JavaScript served from my own origin," while object-src 'none' blocks legacy plugins entirely.

Why it matters

Without CSP, any HTML-injection or XSS bug lets an attacker run arbitrary JavaScript in your users' browsers — stealing sessions, rewriting the page, or exfiltrating data.

A weak CSP is almost as bad as none. 'unsafe-inline' re-allows the inline scripts attackers rely on, and a wildcard source like script-src * lets script load from anywhere, defeating the point.

How to fix it

Add a baseline policy in Next.js

Set the header in next.config.js so it applies to every response. Start strict and loosen only where needed.

// next.config.js
const csp = [
  "default-src 'self'",
  "script-src 'self'",
  "style-src 'self' 'unsafe-inline'",
  "img-src 'self' data:",
  "base-uri 'none'",
  "frame-ancestors 'none'",
  "object-src 'none'",
].join("; ");

module.exports = {
  async headers() {
    return [{ source: "/:path*", headers: [{ key: "Content-Security-Policy", value: csp }] }];
  },
};
Replace unsafe-inline with nonces

If you need inline scripts, generate a per-request nonce and add it to both the script tag and the policy (script-src 'self' 'nonce-<value>') instead of using 'unsafe-inline'.

Always set the hardening directives

base-uri 'none', frame-ancestors 'none', and object-src 'none' close common bypasses (base-tag injection, clickjacking, and plugin embedding) and are safe defaults for most apps.

FAQ

Does a CSP slow my site down?

No. CSP is just a header the browser evaluates; it adds no measurable latency. The real cost is the engineering work to remove inline scripts.

What is the difference between Content-Security-Policy and X-Frame-Options?

X-Frame-Options only controls framing (clickjacking). CSP's frame-ancestors directive supersedes it and CSP also governs scripts, styles, images, and more.

Is your app affected?

AppSafe checks for this and dozens of other issues in one free scan.

Scan my app free
Content-Security-Policy (CSP) Explained — How to Add One