Why it matters
A CSP is a second line of defence against cross-site scripting. Good code should stop injection in the first place. If a mistake slips through, a strict policy can stop the browser from running the attacker's script or sending data to the attacker's server. It also limits which sites may embed your pages, which helps against clickjacking.
Key directives
| Directive | What it controls |
|---|---|
| default-src | The fallback for any type you do not set |
| script-src | Where scripts may come from, and whether inline scripts run |
| style-src | Where styles may come from |
| connect-src | Which addresses the page's code may connect to |
| frame-ancestors | Which sites may embed this page in a frame |
How to roll it out
- Start in report-only mode, with the Content-Security-Policy-Report-Only header. The browser reports what it would have blocked without blocking it.
- Review the reports and list every script, style and service the site really needs, including analytics, chat widgets and payment frames.
- Prefer nonces or hashes for inline scripts over allowing all inline code.
- Switch to enforcing mode, and keep a reporting endpoint so you can see what breaks.
Common mistakes
- Adding unsafe-inline to script-src, which removes most of the protection.
- Allowing wildcard or very broad hosts, such as a whole CDN, that attackers can use too.
- Copying a policy from a blog post without testing it, then breaking checkout or sign-in.
- Treating a CSP as a replacement for fixing the flaw itself.
Related terms
See cross-site scripting for the attack a CSP limits, and the OWASP Top 10 for where it fits in the larger picture. Our secure by default web checklist is a practical place to start.