
- 01CSP allowlists were never a great defense — with tag managers, ad SDKs, and analytics they grow until any value above 'easy to bypass' is lost. Treat a long CDN allowlist as CSP theater.
- 02The pattern that actually defends: per-request nonce on legitimate scripts, header `script-src 'nonce-...' 'strict-dynamic'`, browser allows nonce-bearing scripts and what they dynamically load. Allowlists become unnecessary.
- 03What it blocks: reflected and stored XSS via injected `<script>`, injection of `<script src=...>` to attacker-controlled domains, and most off-the-shelf XSS payloads.
- 04Pair CSP with Trusted Types for DOM XSS coverage. Inline event handlers (onclick, etc.) require nonces, hashes, or refactoring — refactoring is almost always the right answer.
CSP allowlists were never a great defense. With third-party tag managers, ad SDKs, and analytics, the lists grew until any value above 'easy to bypass' was lost. The strict-dynamic + nonce pattern, supported in all modern browsers, is a real upgrade.
The pattern
Per-request nonce attached to legitimate scripts. CSP header with `script-src 'nonce-...' 'strict-dynamic'`. Browser allows nonce-bearing scripts and any scripts they dynamically load. Inline scripts without the nonce are blocked. Allowlists become unnecessary.
What it actually blocks
- 01Reflected and stored XSS via injected `<script>` tags
- 02Injection of `<script src=...>` to attacker-controlled domains
- 03Most off-the-shelf XSS payloads
Caveats
Trusted Types should accompany CSP for DOM XSS coverage. Older browsers (you probably do not need to support them, but check) ignore strict-dynamic. Inline event handlers (onclick, etc.) require either nonces, hashes, or refactoring — typically the latter.

