← The ten steps · Step 8 of 10 · 6 minutes
Third parties and the real rollout
Everything so far works on a site you fully control. Now for the other kind.
The rollout that works
- Report-only, strict, from day one. Not a loose policy you plan to tighten — the policy you actually want, in report-only. It cannot break anything, so there is no reason to be timid with it.
- Collect for a full business cycle. A week minimum. You need the Monday morning traffic, the campaign that only runs on Fridays, and the checkout flow nobody tests.
- Triage the reports. Discard extension noise. What remains is your real inventory.
- Fix, do not widen. For each finding, prefer nonce-ing the script over adding a host. Adding hosts is how you end up back in step 5.
- Enforce, keeping report-only for the next tightening. Both headers, always. The enforced one protects users; the report-only one is your next move.
Tag managers
A tag manager is a script that loads arbitrary other scripts chosen by people outside engineering.
That is precisely what 'strict-dynamic' is for: nonce the container snippet and everything
it loads inherits trust, with no host list to maintain as marketing adds vendors.
It is worth being honest about what that means. You have made the tag manager a trusted execution path, so whoever can add a tag can run code on your site. CSP has not removed that risk; it has made it explicit and located it in one place. Who has access to that account is now a security control, and should be treated as one.
Payment providers and iframes
Anything that renders in an iframe — a payment field, an embedded video, a support widget — runs under
its own policy, not yours. Your frame-src controls whether the frame may load at
all; what happens inside it is the provider's business.
This is genuinely useful: a payment iframe is isolated from your page, which is why providers ship them. It also means CSP on your page is not evidence about what happens inside theirs.
The scripts that fight back
Some third parties simply do not work under a strict policy. The tells: they inject inline event
handlers, they call eval, they document their own required policy including
'unsafe-inline', or their support answer is "allow-list our whole domain".
Your options, in order of preference: ask the vendor (a support ticket that says "your script requires us to weaken our CSP" carries more weight than you would think, and vendors do fix this); isolate the script in a sandboxed iframe so its policy is not your policy; drop the vendor; or grant the exception with a date on it and a ticket to revisit. What you should not do is quietly weaken the whole policy for one tag and forget why.
Policy drift is the steady state
A policy is never finished, because the site is never finished. Someone adds a font, a vendor changes CDN, a new page loads a new tool. That is why report-only never gets turned off — it is not a phase, it is monitoring. A policy nobody is watching is a policy that will be silently wrong within a quarter.
Two habits that keep it healthy:
- Watch the report volume, not just the reports. A sudden spike usually means someone shipped something. That is worth knowing on the day, not at the next audit.
- Review the policy when it grows. Every new host in
script-srcis a decision to trust another party with code execution. If the list only ever gets longer, the policy is decaying.
You can do this now
List the third-party scripts on your highest-value page — checkout, login, whatever it is. Not from the codebase, from the network tab. Most people find at least one they cannot account for, and that is the finding.