Fix CSP Strict-Dynamic for Trusted Script Propagation
In this tutorial, you'll learn about Fix CSP Strict. We cover key concepts, practical examples, and best practices.
Managing a growing list of CDN domains in script-src is brittle and error-prone. The strict-dynamic CSP mechanism lets you trust a nonce-based script, and then that script can dynamically load any additional scripts. This eliminates the need to list every third-party script domain explicitly while maintaining strong XSS protection.
Wrong
A long, manually maintained list of script source domains that breaks when a new CDN is added or a domain changes.
Content-Security-Policy: script-src 'self' https://cdn.example.com https://cdn2.example.com https://www.google-analytics.com https://maps.googleapis.com
A new dependency loads from https://cdn3.example.com:
Refused to load the script 'https://cdn3.example.com/sdk.js' because it
violates the following Content Security Policy directive: "script-src 'self'
https://cdn.example.com https://cdn2.example.com https://www.google-analytics.com
https://maps.googleapis.com".
Every CDN addition requires a policy update and redeployment.
Right
Use 'strict-dynamic' with a nonce-based approach. Only the initial script needs the nonce. It can then dynamically load scripts from any domain.
Content-Security-Policy: script-src 'nonce-abc123' 'strict-dynamic'
<script nonce="abc123" src="/js/app.js"></script>
Inside app.js, dynamically loaded scripts are trusted:
// This dynamically loaded script is trusted because strict-dynamic
// propagates trust from the nonce-based parent script.
const script = document.createElement('script');
script.src = 'https://cdn3.example.com/sdk.js';
document.head.appendChild(script);
// This works too
import('https://cdn.example.com/module.js').then(m => m.init());
With helmet:
app.use(helmet.contentSecurityPolicy({
directives: {
scriptSrc: [
"'nonce-abc123'",
"'strict-dynamic'",
],
},
}));
When 'strict-dynamic' is present in script-src, browsers ignore 'self' and unsafe-inline in the same directive, so they do not need to be included.
Prevention
- Use
'strict-dynamic'together with'nonce-...'or'sha256-...'to create a strong CSP baseline. - Remove
'self'and'unsafe-inline'fromscript-srcwhen using'strict-dynamic', as browsers ignore them. - Add
https:as a fallback for browsers that do not support'strict-dynamic':script-src 'nonce-abc123' 'strict-dynamic' 'sha256-...' https:. - Use
strict-dynamiconly inscript-src. It does not apply to other CSP directives. - Test in report-only mode first because
strict-dynamicrequires all scripts to be trusted via nonce or hash. - Ensure your application's main script bundle is loaded with a nonce so trust can propagate.
DodaTech Tools
Doda Browser shows trust propagation paths for strict-dynamic in its CSP debugger, highlighting which scripts were trusted directly and which were trusted via propagation. DodaZIP's CSP optimizer recommends strict-dynamic when it detects long CDN whitelists. Durga Antivirus Pro uses strict-dynamic across all its micro-frontend architecture, reducing CSP maintenance to a single nonce per request.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro