CSP.
Controls which scripts can run — primary defense against XSS injection
What does this check test?
Content Security Policy (CSP) is a security header (`Content-Security-Policy`) that defines an allowlist of trusted sources for scripts, styles, images, fonts, and other resources. When a browser receives a CSP, it blocks any resource that does not match the policy. CSP supports directives like `script-src`, `style-src`, `img-src`, `connect-src`, `frame-ancestors`, and `default-src`, giving you granular control over every resource type your page loads.
Why does it matter?
Cross-site scripting (XSS) is consistently one of the most prevalent web vulnerabilities. CSP acts as a defense-in-depth layer that mitigates XSS even when input validation or output encoding fails. By blocking inline scripts and restricting sources, CSP prevents injected scripts from executing. CSP also protects against data exfiltration by controlling which domains your page can connect to via `connect-src`. A well-configured CSP can also prevent clickjacking (via `frame-ancestors`) and mixed content issues.
Who is affected?
Every web application benefits from CSP, but it is especially critical for applications that handle user-generated content, authentication tokens, or sensitive data. Single-page applications (SPAs) and sites with complex third-party integrations should invest in a strict CSP to limit the blast radius of any compromised dependency. Even static marketing sites benefit from CSP to prevent ad injection and content tampering.
Where does this apply?
CSP is set as an HTTP response header on every HTML page response. It can be configured at the web server (Nginx, Apache), CDN (Cloudflare, Fastly), reverse proxy, or application level. For testing, use `Content-Security-Policy-Report-Only` to monitor violations without blocking resources. CSP can also be set via a `<meta>` tag, but this method does not support `frame-ancestors` or `report-uri` and is not recommended for production.
How to fix it
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; style-src 'self'; report-uri /csp-report Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{random}'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https://api.example.com; frame-ancestors 'none' Nginx
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data: https:; frame-ancestors 'none'" always; Node.js / Express
const helmet = require('helmet');
app.use(helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
frameAncestors: ["'none'"]
}
})); Django
CSP_DEFAULT_SRC = ("'self'",)
CSP_SCRIPT_SRC = ("'self'",)
CSP_STYLE_SRC = ("'self'", "'unsafe-inline'")
CSP_IMG_SRC = ("'self'", "data:", "https:")
CSP_FRAME_ANCESTORS = ("'none'",) Flask
from flask_talisman import Talisman
csp = {
'default-src': "'self'",
'script-src': "'self'",
'style-src': "'self' 'unsafe-inline'",
'img-src': "'self' data: https:"
}
Talisman(app, content_security_policy=csp) Next.js
// middleware.ts
import { NextResponse } from 'next/server';
export function middleware(request) {
const nonce = Buffer.from(crypto.randomUUID()).toString('base64');
const csp = `default-src 'self'; script-src 'self' 'nonce-${nonce}'; style-src 'self' 'unsafe-inline'`;
const response = NextResponse.next();
response.headers.set('Content-Security-Policy', csp);
return response;
} Spring Boot
http.headers().contentSecurityPolicy(
"default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; frame-ancestors 'none'"
); References
- MDN: Content-Security-Policy
- web.dev: Content Security Policy
- OWASP: Content Security Policy Cheat Sheet
- CSP Evaluator (Google)
AppVet checks CSP automatically
Run a free security scan and get a full report with actionable fixes, including a Fix with AI prompt you can paste into any coding tool.
Run Audit