Skip to content

Fix CSP Strict-Dynamic for Trusted Script Propagation

DodaTech Updated 2026-06-26 2 min read

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.

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' from script-src when 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-dynamic only in script-src. It does not apply to other CSP directives.
  • Test in report-only mode first because strict-dynamic requires 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

### How does strict-dynamic trust propagation work?

When a script loads via a nonce or hash that matches the CSP, that script is trusted. When that trusted script creates a new script element (via document.createElement('script')) or uses import(), the new script is also trusted. Trust propagates through the script execution chain, not by URL or domain.

Which browsers support strict-dynamic?

'strict-dynamic' is supported in Chrome 52+, Firefox 52+, Safari 15.4+, and Edge 79+. For older browsers that do not support 'strict-dynamic', include a fallback like https: at the end of script-src: script-src 'nonce-abc123' 'strict-dynamic' https:. Older browsers ignore 'strict-dynamic' and fall back to https:.

Do I still need 'self' when using strict-dynamic?

No. When 'strict-dynamic' is present, the browser ignores 'self' and 'unsafe-inline' in the same script-src directive. The nonce or hash is the only source that matters. However, some CSP validators expect 'self' to be present, so check your specific tooling requirements.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro