HTTP headers · Response

Content-Security-Policy

Content-Security-Policy restricts which sources a page may load and execute.

Key facts

TypeResponse
Key directives<code>default-src</code>, <code>script-src</code>
Navigation<code>frame-ancestors</code>, <code>form-action</code>
Nonces<code>'nonce-...'</code>
Hashes<code>'sha256-...'</code>
Report only<code>Content-Security-Policy-Report-Only</code>
InlineBlocked without nonce, hash or unsafe-inline
StandardCSP Level 3

An allowlist for the page

CSP tells the browser which origins may supply scripts, styles, images, fonts, frames and connections. default-src is the fallback; specific directives override it. A strict policy blocks injected inline scripts, which removes most cross-site scripting payloads even when an injection point exists.

The strongest common pattern is a per-response nonce on every legitimate script tag plus 'strict-dynamic' for scripts those scripts load. Hashes work for static inline code but require updating the policy whenever the code changes.

Rolling it out without breaking the site

Start with Content-Security-Policy-Report-Only and collect violation reports. Then move directives into enforcement one at a time. Inline event handlers, eval, third-party widgets and data: images are the usual breakages.

CSP is defence in depth, not a substitute for output encoding. frame-ancestors replaces X-Frame-Options for clickjacking, and form-action limits where forms can submit, which blocks a common exfiltration path.

Frequently asked questions

Does CSP stop all XSS?

No. It stops inline and unauthorized script execution, but DOM-based sinks, allowed origins and misconfigurations can still be exploited.

Can I set CSP with a meta tag?

Some directives work in meta, but frame-ancestors and reporting do not. A response header is the reliable place.

New tools, straight to your inbox

One short email when we add tools worth using. No spam, unsubscribe anytime.