Without a Content-Security-Policy, any XSS vulnerability in your app becomes a full code execution primitive — injected scripts can exfiltrate cookies, keylog form inputs, or pivot to your users' other browser contexts. CSP is the browser-enforced last line of defense: even when input sanitization fails, a tight policy prevents injected scripts from loading external resources or executing inline. OWASP A03 (Injection) and A05 (Security Misconfiguration) both call out missing CSP as a critical gap; CWE-79 names the XSS class that a CSP directly mitigates. Without it, a single missed sanitization anywhere in your rendering pipeline becomes an account-takeover vector.
High because the absence of any CSP removes the last browser-enforced barrier against XSS exploitation, leaving injected scripts with unrestricted execution access.
Add a Content-Security-Policy header starting with a restrictive default-src 'self' and expand from there based on what your app actually loads. Start minimal and use browser console violation reports to tune.
// next.config.js
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'"
}]
If your app uses third-party scripts, add their domains explicitly (script-src 'self' https://cdn.example.com) rather than using the wildcard *. For inline scripts, use nonces rather than unsafe-inline — see the csp-no-unsafe-inline pattern for the nonce implementation.
ID: security-headers.headers.csp-present
Severity: high
What to look for: Count all locations where a Content-Security-Policy could be defined: framework config headers, middleware, deployment config, and <meta http-equiv="Content-Security-Policy"> tags. A basic CSP that defines at least 1 directive (default-src) counts.
Pass criteria: A CSP header or meta tag is present with at least 1 default-src directive that is not set to the wildcard value * alone. The directive must restrict sources to a defined set (e.g., 'self', specific domains, or nonce/hash patterns). A well-configured CSP typically defines at least 3 directives (e.g., default-src, script-src, style-src).
Fail criteria: No CSP configuration found anywhere in the project, or CSP is present but default-src is set to * with no other restricting directives.
Do NOT pass when: CSP is present but set to report-only mode (Content-Security-Policy-Report-Only) without an accompanying enforcement policy (Content-Security-Policy). Report-only without enforcement provides monitoring but no protection.
Skip (N/A) when: Never — CSP is essential for any web project.
Cross-reference: For XSS prevention beyond CSP, the Client-Side Framework Security audit covers DOM-based protections, sanitization, and safe rendering patterns.
Detail on fail: "No Content-Security-Policy header configured in next.config.js, middleware, or meta tags"
Remediation: CSP tells browsers what resources your page is allowed to load, preventing XSS and data injection attacks. Start with a basic policy:
// next.config.js
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'"
}]
Refine the policy based on your actual resource needs. Use browser console CSP violation reports to identify what to allow.