headers14 min readUpdated 2026-01-10

Content Security Policy (CSP): What It Is and How to Ship It

Content Security Policy is the single most effective defense against cross-site scripting. It is also the header most often shipped wrong — either so loose it does nothing, or so strict it breaks the app on deploy day. Here is the pragmatic path.

What CSP does

CSP tells the browser which origins are allowed to load scripts, styles, images, fonts, media, frames and workers. If your app is compromised via an injection bug, the browser will refuse to run attacker-supplied resources.

A modern strict policy

Nonce-based, with strict-dynamic. Works in every current browser:

Content-Security-Policy: default-src 'self'; script-src 'nonce-RANDOM' 'strict-dynamic' https:; object-src 'none'; base-uri 'self'; frame-ancestors 'none'; require-trusted-types-for 'script'

Roll it out in report-only mode

Ship Content-Security-Policy-Report-Only first with report-to configured. Collect a week of reports, allowlist the third parties you actually need, then flip to enforcement.

Common mistakes

Adding 'unsafe-inline' to make it work — this defeats the header. Using report-uri without report-to (report-uri is deprecated). Forgetting to include base-uri and object-src, which allow bypasses even with a strict script-src.

Frequently asked questions

Yes. WAFs block payloads on the way in; CSP blocks execution in the browser. They are complementary, not redundant.

Try it on your site

Run a free Website Auditor scan and see which of these controls you're missing.

Run a scan

Related tools

More guides