CSP Academy

← The ten steps · Step 10 of 10 · 5 minutes

Ship it

Everything from the last nine steps, on one page, in the order you should do it.

The policy

Content-Security-Policy-Report-Only:
  default-src 'self';
  script-src 'nonce-{RANDOM}' 'strict-dynamic';
  style-src 'self';
  img-src 'self';
  connect-src 'self';
  object-src 'none';
  base-uri 'none';
  form-action 'self';
  frame-ancestors 'none';
  report-uri <your endpoint>

{RANDOM} is at least 128 bits from your platform's secure random source, generated fresh on every response, placed on every script tag you render. The response carrying it must be Cache-Control: no-store.

The order

  1. Report-only, strict, everywhere. It cannot break anything, so there is no reason to roll it out gradually.
  2. Wait a week. A full business cycle, including the traffic you do not think about.
  3. Triage. Discard extension noise. Everything left is a real finding.
  4. Fix by nonce-ing, not by allowlisting. Widen img-src, style-src and connect-src as needed; resist widening script-src.
  5. Enforce. Move the policy to Content-Security-Policy and put your next tightening into report-only behind it.

What to watch afterwards

How you know you are done

You are not, and that is the correct state. A CSP is not a project with an end date; it is a control that reflects what your site loads, and your site changes. "Done" looks like: an enforced strict policy, a report-only policy one notch tighter behind it, reports going somewhere a human occasionally reads, and someone who notices when the volume changes.

If you only do three things

  1. Deploy Content-Security-Policy-Report-Only today. It cannot break anything.
  2. Add base-uri 'none'; form-action 'self'; frame-ancestors 'none'; object-src 'none'. Four lines, four real attacks, no rollout required.
  3. Get the reports somewhere you will actually look.

The last thing

A policy you cannot see is a policy you cannot trust. Reports are what turn CSP from a header you wrote once into a control that tells you when your site changes underneath you. Send them to Report URI, which sponsors this site, or run your own endpoint — a violation report is a JSON POST and a few dozen lines of code. What matters is that they go somewhere.

Where to go next

Check your policy →

Paste what you have now and see what the analyser makes of it.

When something breaks →

Paste the console error and get the explanation and the fix.

Directive reference →

The detail behind each directive, one page at a time.

Watch it work →

Live demos on the Report URI demo site: script injection, Magecart, form hijacking and XSS, each with the policy off and on.