security

Content-Security-Policy

Restricts which sources of scripts, styles, images, frames, and other resources a page may load, mitigating XSS and data injection. Policies are a semicolon-separated list of directives, each with a source list ('self', 'none', hostnames, schemes, nonces, or hashes).

Content-Security-Policy: <directive> <source-list>; <directive> <source-list>; ...

Common directives / values

Directive Purpose
default-src Fallback source list for any fetch directive not otherwise specified.
script-src Allowed sources for JavaScript; accepts 'nonce-<b64>' and 'sha256-<b64>'.
style-src Allowed sources for CSS, including <style> and inline style attributes when 'unsafe-inline' is set.
connect-src Allowed endpoints for fetch, XHR, WebSocket, EventSource, and beacon.
img-src Allowed image sources; commonly includes data: for inline images.
frame-ancestors Which origins may embed this page in <frame>/<iframe> — the modern X-Frame-Options.
'self' Same origin (scheme+host+port) as the protected document.
'nonce-<base64>' Per-request nonce whitelisting inline scripts/styles that carry the matching nonce attribute.

Examples

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-r4nd0m'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self' https://api.example.com; frame-ancestors 'none'

Solid app baseline — inline scripts allowed only with the correct nonce.

Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report

Report-only mode logs violations to /csp-report without blocking — use to trial a policy.

Content-Security-Policy: default-src 'none'; frame-ancestors 'self'

Extremely restrictive — good for API endpoints that serve no HTML.

Content-Security-Policy: script-src 'strict-dynamic' 'nonce-abc' 'unsafe-inline' https:; object-src 'none'; base-uri 'none'

Modern 'strict-dynamic' policy: legacy allowlists are ignored, only nonce-approved scripts (and what they load) run.

Gotcha

Two often-conflated fallback mechanisms: (1) When any nonce-source or hash-source is present in script-src, 'unsafe-inline' is IGNORED by CSP2+ browsers — this is a compatibility fallback for CSP1 browsers that still honor 'unsafe-inline'. (2) 'strict-dynamic' does something different: it causes host- and scheme-source allowlists to be IGNORED, and lets scripts trusted via nonce/hash propagate trust to scripts they dynamically load.

Related headers

← All HTTP headers · HTTP status codes · Fix CORS errors