My backend service generates a Content Security Policy as the following:
Content-Security-Policy
default-src 'self'; frame-ancestors 'self'; form-action 'self'; script-src 'nonce-4VOtk0Uo1l7pwtC';
The rendered HTML uses nonce in the script tags to allow its execution:
<script nomodule src="https://xxx/build/script1.js" nonce="4VOtk0Uo1l7pwtC"></script>
<script type="module" src="https://xxx/build/script2.js" nonce="4VOtk0Uo1l7pwtC"></script>
These script are loaded correctly. The problem is script2.js includes an import statement to load another script:
import{p as e,b as t}from"./p-cfa9fa8a.js";
This one is blocked by the csp policy, as it doesn't include the nonce parameter:
TypeError: error loading dynamically imported module undefined p-cfa9fa8a.js:1:12156
Content Security Policy: The page’s settings blocked the loading of a resource at inline (“default-src”). p-cfa9fa8a.js:1:12156
The solution was to add the 'strict-dynamic' option:
The strict-dynamic source expression specifies that the trust explicitly given to a script present in the markup, by accompanying it with a nonce or a hash, shall be propagated to all the scripts loaded by that root script. At the same time, any allow-list or source expressions such as 'self' or 'unsafe-inline' are ignored. See script-src for an example.
Content-Security-Policy
default-src 'self'; frame-ancestors 'self'; form-action 'self'; script-src 'strict-dynamic' 'nonce-4VOtk0Uo1l7pwtC';