Content Security Policy Cheat Sheet
Quick reference for Content-Security-Policy: source expressions, directive reference, common policy templates, and reporting.
CSP is a browser security header that restricts which resources a page may load. It is the strongest defense-in-depth control against XSS: even if a script is injected, the browser refuses to execute it if the policy does not allow it.
Directive Reference
| Directive | Controls | Example |
|---|---|---|
default-src | Fallback for all other -src directives | default-src 'self' |
script-src | JavaScript sources | script-src 'self' |
style-src | Stylesheets and inline styles | style-src 'self' 'unsafe-inline' |
img-src | Images | img-src 'self' data: https: |
font-src | Fonts | font-src 'self' https://fonts.gstatic.com |
connect-src | Fetch/XHR/WebSocket endpoints | connect-src 'self' https://api.example.com |
frame-src | Iframes | frame-src 'self' https://player.vimeo.com |
frame-ancestors | Who may embed this page in an iframe | frame-ancestors 'none' |
object-src | <object>, <embed>, <applet> | object-src 'none' |
base-uri | Valid <base> targets | base-uri 'self' |
form-action | Valid form submission targets | form-action 'self' |
worker-src | Web workers | worker-src 'self' blob: |
media-src | Audio/video | media-src 'self' |
upgrade-insecure-requests | Auto-upgrade HTTP to HTTPS | upgrade-insecure-requests |
Source Expressions
| Source | Meaning |
|---|---|
'self' | Same origin only |
'none' | Block all |
'unsafe-inline' | Allow inline scripts/styles (avoid for scripts) |
'unsafe-eval' | Allow eval() (avoid) |
'strict-dynamic' | Trust scripts loaded by already-trusted scripts |
'nonce-<base64>' | Allow a specific inline script/event by nonce |
'sha256-<base64>' | Allow an inline script matching the hash |
https: | Any HTTPS origin |
https://example.com | Specific origin (scheme+host) |
wss: | Any secure WebSocket |
data: | data: URIs |
blob: | blob: URIs |
Nonces — Recommended Pattern
Nonces are the modern replacement for 'unsafe-inline'. Generate a fresh value per response, add it as an attribute to allowed inline scripts, and reference it in the policy.
Content-Security-Policy: default-src 'self'; script-src 'nonce-8f3k9s2n' 'strict-dynamic'
<script nonce="8f3k9s2n">
app.init();
</script>
Starter Policies
# Strict, no third-party scripts
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'
# Allow Google Analytics + self scripts (nonce-based)
Content-Security-Policy: script-src 'self' 'nonce-<RANDOM>' https://www.googletagmanager.com; img-src 'self' https://www.google-analytics.com; connect-src 'self' https://www.google-analytics.com
# Iframe a video player
Content-Security-Policy: default-src 'self'; frame-src 'self' https://player.vimeo.com
Reporting
Report violations without blocking by using Content-Security-Policy-Report-Only first. The report endpoint receives a JSON body listing the violated directive and blocked resource.
Content-Security-Policy-Report-Only: default-src 'self'; report-to csp-endpoint
Report-To: { "group": "csp-endpoint", "max_age": 10886400, "endpoints": [{ "url": "https://example.com/csp-reports" }] }
Common Pitfalls
[!WARNING]
'unsafe-inline'inscript-srcdefeats the purpose of CSP — replace inline handlers with nonces or hashes before hardening.
[!TIP] Always set
object-src 'none'andbase-uri 'self'— they are cheap, high-value hardening that many default templates omit.