'strict-dynamic' is a CSP keyword that lets a script you trusted with a nonce or hash load further scripts without those scripts needing their own nonce or hash. It makes strict CSPs workable with third-party tags, at the cost of trusting everything those scripts create.
The problem it solves
A strict CSP controls script loading with a nonce or a hash rather than a list of allowed hosts. MDN recommends this approach, and explains why: allowlist policies are hard to get right and often inadvertently allow unsafe domains, and they can grow very large when third-party scripts are involved.
The catch with nonces and hashes is that they apply to tags you wrote. If a trusted script creates another script element at runtime, such as a tag manager injecting an analytics library, the new element has no nonce or hash, so the browser blocks it.
How the keyword changes that
MDN's guide describes it simply. With 'strict-dynamic', a script that has a nonce or hash attached is allowed to load further scripts that do not themselves have nonces or hashes. Trust passes along: to the scripts that script loads, and the ones they load, and so on.
Content-Security-Policy:
script-src 'nonce-RANDOM' 'strict-dynamic';
object-src 'none';
base-uri 'none';
The first two lines of that policy match the nonce based strict CSP in MDN's example, with the keyword added. The nonce must be a fresh unpredictable value on every response.
What you give up
MDN is plain about the tradeoff: the keyword makes the CSP less secure, because if the scripts you include create script elements from potential sources of XSS, the policy will not protect them. In effect, you are betting that each trusted script handles its own inputs safely.
| Approach | Maintenance | Protection |
|---|---|---|
| Host allowlist | Grows with each vendor | Weak if any allowed host serves attacker influenced content |
| Nonce or hash only | Every script needs a nonce or hash | Strong, but breaks dynamic loaders |
| Nonce or hash plus strict-dynamic | Much lower | Good, but depends on trusted scripts being careful |
Steps to adopt it
- Remove inline event handlers,
javascript:URLs andeval()calls. MDN says these need refactoring even with nonces. - Generate a nonce per response on the server, and add it to every script tag you author.
- Add
'strict-dynamic'alongside the nonce. - Start with
Content-Security-Policy-Report-Onlyand read the violation reports. - Enforce when the reports go quiet, keeping
object-src 'none'andbase-uri 'none'.
Static sites cannot mint a nonce per response, so use hashes for the scripts you author. MDN notes the downside: you must recompute the hash whenever a script changes.
Try it yourself
Open the dependency inventory to see how many packages and third-party components a typical front end pulls in, then ask which of them create scripts at runtime.
Click through it at your own pace, or open it full screen.
Quick check
Do I still need nonces with strict-dynamic?
Yes. The keyword extends trust from scripts that already carry a nonce or hash. Without a starting point, nothing is trusted.
Does it remove the need to audit third-party scripts?
No. It makes the opposite true: every script you trust can load more, so the vendor review matters more.
Safeguard's dependency scanning and SBOM generation show what third-party code your app includes, and its policies can block a risky package in a pull request. Run a free scan at gold.safeguard.sh/scan.
Sources
Last reviewed: 19 October 2026.