CSP for scripts from google.com not working any more

For many years, this code used to work, as suggested by the docs Controllers — Nextcloud latest Developer Manual latest documentation

PageController.php:

$response = new TemplateResponse('myApp', 'main', $params)
$csp = new ContentSecurityPolicy();
$csp->addAllowedScriptDomain("maps.googleapis.com");
$response->setContentSecurityPolicy($csp);

main.html:

<script async='true' defer src="https://maps.googleapis.com/maps/api/js?key=theKey"></script>

This is failing now with a CSP violation of "script-src-elem 'strict-dynamic' 'nonce-redacted=' http://maps.googleapis.com http://developers.google.com"

Playing with allowXXX on the policy doesn’t change the resulting policy finally rendered.
Any hint how I can re-enable external scripts?

http for the scheme versus https. We don’t set a default scheme (if not specified) for CSP anywhere I see so not sure where the http is coming from in your environment.

You can try this to be explicit about the scheme:

$csp->addAllowedScriptDomain("https://maps.googleapis.com");

But based on the code you provided, it’s not clear why you’re even ending up with the http scheme in the policy so this may not make any difference in your case.

Are you sure you’re not overriding Nextcloud’s CSP policy somewhere else?

The instance I’m testing with is not ssl-enabled, that’s probably why http is added implicitely. When specifying $csp->addAllowedScriptDomain("https://maps.googleapis.com"), this changes to https in the server request as well. I upgraded my developer instance to https, and now the content-security-policy contains maps.googleapis.com only.

Investigating my environments further, things get more confusing. I have three installations, all having the very same Debian, Apache and NC30.0.2.

Developer and Test site both deliver the very same response header (less the nonce), but the browser will the CSP error “blocked maps.googleapis.com, violating script-src-elem” as mentioned above for the dev site only. Both sites show a warning “Content-Security-Policy: Ignorieren von “https://maps.googleapis.com” innerhalb script-src-elem: ‘strict-dynamic’ angegeben” and do not load the google script.
The production site generates a slightly different CSP:

default-src 'none';base-uri 'none';manifest-src 'self';
script-src 'nonce-+pDb78qEyNosQaXVyHue3nDs2ceeaB3G/b/g6o5Clkw=' blob: maps.googleapis.com developers.google.com;
script-src-elem 'strict-dynamic' 'nonce-+pDb78qEyNosQaXVyHue3nDs2ceeaB3G/b/g6o5Clkw=' blob: maps.googleapis.com developers.google.com;(...)

and another warning is logged on the console:
Content-Security-Policy: Ignorieren von “blob:” innerhalb script-src-elem: ‘strict-dynamic’ angegeben

This tests were performed with Firefox. Using Chrome, there’s one additional helpful message: “Note that ‘strict-dynamic’ is present, so host-based allowlisting is disabled.” which does explain, why m.g.c isn’t loaded.

With this new insight, I tried $csp->useStrictDynamic() and $csp->useStrictDynamicOnScripts() with false and with true argument, but the CSP is always generated with strict-dynamic.

Finally, instead of loading from the main.html via script tag, I load from a script now, which does work correctly.

Lesson learned: ContentSecurityPolicy:addAllowedScriptDomain() isn’t working for external domains any more.