Skip to content

Content Security Policy Explained (Without Tears)

What CSP actually does, why most policies fail open, a starter policy you can ship today, and how to roll it out report-only without breaking things.

Overlapping browser windows on a monitor

Short answer

CSP tells the browser which sources may load scripts, styles, images, and more. It is the strongest browser-side control against injected scripts when you enforce it carefully - start report-only, then tighten.

What CSP is for

A Content-Security-Policy is an allowlist the browser enforces on every page load. Injected script that violates the policy simply does not run. That is a different layer from server auth - it protects the client even when something else went wrong.

XSS still needs fixing at the source. CSP is the seatbelt that still helps when a bug slips through.

Why most policies fail open

unsafe-inline and unsafe-eval in script-src undo much of the value. They are common because a strict CSP takes iteration across real pages, third-party widgets, and legacy templates.

That is why report-only mode exists: learn what your real pages load before you break checkout. Shipping enforce with a wide-open policy is theatre.

A sane rollout

Ship Content-Security-Policy-Report-Only with a tight default-src. Collect violations for a week. Fix legitimate sources (or drop dead scripts). Then switch to enforcing CSP and re-scan.

Framework sites often need nonces or hashes. Budget time for that. Do not give up and re-open the policy to "anything goes" just to silence the console.

Not a silver bullet

CSP does not replace HTTPS, authentication, or patching. It is one strong control in a set. Pair it with HSTS, framing controls, and nosniff so a single missing header does not define your whole posture.

When a scan still complains, read the violated directive. Blindly adding hosts to the allowlist is how CSP becomes wallpaper.

Config to copy

Content-Security-Policy-Report-Only: default-src 'self'; img-src 'self' data: https:; style-src 'self' 'unsafe-inline'

Paste carefully. Test on staging first if the setting can lock users out.

What to do this week

  1. Enable CSP Report-Only on staging with a tight default-src.
  2. Collect one week of violations; fix real sources or remove dead scripts.
  3. Flip to enforce on production after the noise dies down.
  4. Re-scan and keep the policy next to your header deploy notes.

Report-only first. Enforce second. Never ship unsafe-inline forever.

Run a free security grade on your domain · Pricing

Update log (1)

2026-05-02Editorial form rewrite for length and uniqueness.

Sources + verification

Practical guidance based on mainstream browser behavior, common reverse-proxy configuration, and widely published RFCs and vendor docs. Verify on your own stack with curl, browser devtools, and a re-scan after each change.

Keep reading

Tooling The five headers that fix most of a failed scan 2026-05-06 Breach Third-Party Scripts: SRI and the Integrity Gap 2026-06-26 Tooling Add Security Headers: Nginx, Apache & Cloudflare 2026-05-04