angular/angular-cli

application builder - strict-dynamic - issues with content security policy

joergbaier opened this issue · 2 comments

Command

build

Is this a regression?

  • Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

@angular-devkit/build-angular:browser

Description

This is a follow up to #26330 and appreciate the work on adding the preloadInitial flag.

It seems like the real issue is the way chunks are loaded by esbuild (screenshots below):

  • webpack created a runtime.js file that loads scripts in a way that worked with strict-dynamic
  • esbuild calls import ... from "chunk.js"; directly from main.js

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#strict-dynamic

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 allowlist or source expressions such as 'self' or 'unsafe-inline' will be ignored.

Based on that documentation I would expect both cases to work. For the esbuild case, we are allowing main.js via sha384, which should then be allowed to import further scripts. Is there something I am missing here?

Minimal Reproduction

@angular-devkit/build-angular:browser output

<script
  src="runtime.123.js"
  type="module"
  crossorigin="anonymous"
  integrity="sha384-123"
></script>
<script
  src="polyfills.123.js"
  type="module"
  crossorigin="anonymous"
  integrity="sha384-123"
></script>
<script
  src="main.123.js"
  type="module"
  crossorigin="anonymous"
  integrity="sha384-123"
></script>

Chrome trace for loading the first chunk
webpack


@angular-devkit/build-angular:application output

<script
  src="polyfills-123.js"
  type="module"
  crossorigin="anonymous"
  integrity="123"
></script>
<script
  src="main-123.js"
  type="module"
  crossorigin="anonymous"
  integrity="123"
></script>

Chrome trace for loading the first chunk
esbuild

Chrome console error

Refused to load the script '.../chunk-123.js' because it violates the following Content Security Policy directive:
"script-src ... 'sha384-123' 'strict-dynamic'".
Note that 'strict-dynamic' is present, so host-based allowlisting is disabled.
Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.

Exception or Error

No response

Your Environment

17.3

Anything else relevant?

No response

I forgot to mention this fails in Chrome and Firefox, however Safari allows the scripts.

Relevant reading (will update as I find more)