Content Security Policy (CSP)
Quick Reference
| Directive | Purpose | Example |
|---|---|---|
| default-src | Fallback for all resource types | 'self' |
| script-src | JavaScript sources | 'self' 'nonce-abc123' |
| style-src | CSS sources | 'self' 'unsafe-inline' |
| img-src | Image sources | 'self' data: https: |
| connect-src | AJAX, WebSocket, fetch targets | 'self' https://api.example.com |
| frame-ancestors | Who can embed this page | 'self' (replaces X-Frame-Options) |
Why CSP Matters
CSP is one of the most powerful defenses against XSS attacks. Even if an attacker finds an XSS vulnerability in your application, a strict CSP can prevent their injected script from executing. By default, a CSP with script-src that does not include 'unsafe-inline' will block inline scripts, which is how most XSS payloads are delivered.
Implementing CSP effectively requires understanding your application's resource loading patterns. Start with Content-Security-Policy-Report-Only to monitor what would be blocked without actually breaking anything. Once you have identified all legitimate resource sources, switch to enforcing mode.
A common mistake is setting an overly permissive CSP (like script-src *) that provides no real protection. An effective CSP uses specific domains or nonce-based policies. The strictest and most recommended approach is nonce-based CSP with strict-dynamic, which only allows scripts that carry a server-generated nonce.
How to Verify
A security audit checks for the Content-Security-Policy header and evaluates its strictness. The audit identifies overly permissive directives and missing protections. Use report-uri or report-to to collect violation reports during rollout.