Bug #106567
openBackend login broken when applying recommended strict-dynamic CSP mutation
0%
Description
TYPO3 12 introduces a GoogleMapsHelper PHP class that provides recommendations for configuring the Content Security Policy (CSP) when violations are detected in the backend module "Content Security Policy".
Among the suggestions, the following mutation is recommended by TYPO3 to address issues related to Google Maps:
new Mutation( MutationMode::Extend, Directive::ScriptSrcElem, SourceKeyword::strictDynamic, // requires(!) Nonce everywhere SourceScheme::https, // thx Google! SourceKeyword::unsafeEval, // thx Google! SourceScheme::blob, // thx Google! ),
However, when applying this recommended mutation in TYPO3 13.4.9, the backend login becomes inaccessible. The browser (tested in Google Chrome) blocks required JavaScript files due to the presence of 'strict-dynamic' in the script-src-elem directive.
Here are excerpts of the error messages from the browser console:
Refused to load the script 'https://typo313.ddev.site/_assets/1ee1d3e909b58d32e30dcea666dd3224/JavaScript/Contrib/bootstrap.js?bust=1744616604' because it violates the following Content Security Policy directive: "script-src-elem 'self' 'nonce-aui6eSHIzC2VbdLGkCYA__eI24tsAGFdRv528lUt1VDu_OkIf_9YUQ' 'strict-dynamic' https: 'unsafe-eval' blob: 'report-sample'". Note that 'strict-dynamic' is present, so host-based allowlisting is disabled. Understand this error login:1 Refused to load the script 'https://typo313.ddev.site/_assets/081fa96a07de1dccb64a8a83e1567439/JavaScript/login.js?bust=1744616604' because it violates the following Content Security Policy directive: "script-src-elem 'self' 'nonce-aui6eSHIzC2VbdLGkCYA__eI24tsAGFdRv528lUt1VDu_OkIf_9YUQ' 'strict-dynamic' https: 'unsafe-eval' blob: 'report-sample'". Note that 'strict-dynamic' is present, so host-based allowlisting is disabled. Understand this error login:1 Refused to load the script 'https://typo313.ddev.site/_assets/081fa96a07de1dccb64a8a83e1567439/JavaScript/user-pass-login.js?bust=1744616604' because it violates the following Content Security Policy directive: "script-src-elem 'self' 'nonce-aui6eSHIzC2VbdLGkCYA__eI24tsAGFdRv528lUt1VDu_OkIf_9YUQ' 'strict-dynamic' https: 'unsafe-eval' blob: 'report-sample'". Note that 'strict-dynamic' is present, so host-based allowlisting is disabled.
Updated by Oliver Hader 14 days ago
- Related to Task #101297: Render JavaScript modules as script tag if possible added
Updated by Oliver Hader 14 days ago
It seems that the behavior changed between TYPO3 v13.4.8 and v13.4.9 due to https://review.typo3.org/c/Packages/TYPO3.CMS/+/88778/2/typo3/sysext/core/Classes/Page/JavaScriptRenderer.php
That change introduced script tags for modules, that omit the nonce
attribute, e.g.
<script type="module" async="async" src="/typo3/sysext/core/Resources/Public/JavaScript/Contrib/bootstrap.js?bust=0c4e085eac302733d37cf4a77be1e406d3cb7aea"></script> <script type="module" async="async" src="/typo3/sysext/backend/Resources/Public/JavaScript/login.js?bust=0c4e085eac302733d37cf4a77be1e406d3cb7aea"></script> <script type="module" async="async" src="/typo3/sysext/backend/Resources/Public/JavaScript/user-pass-login.js?bust=0c4e085eac302733d37cf4a77be1e406d3cb7aea"></script>
Updated by Benjamin Franzke 14 days ago
- Status changed from New to Rejected
the following mutation is recommended by TYPO3
Where did you find this information?
It's not recommended by TYPO3.
TYPO3 v13.4.8 happened to work with strict-dynamic
, because we used scripts with inline contents and therefore had to supply nonces, but it was never recommended, not even officially supported.
I'm very sorry use inadvertently assumed this could actually be supported.. But the nature of strict-dynamic
is unfortunately very problematic and completely deactivates script-src self
, this is really not just a mutation, it is a complete CSP change :(
Since v13.4.9 we're using script tags without nonces, since this is what is being defined to be allowed by our backend CSP via script-src self
.
Adding a nonce to all generated tags - for the possibility that someone mutated the backend CSP to add strict-dynamic - would result in the consequence, that <script type="module">
tags will never be frontend cacheable. Therefore that would not be an acceptable workaround IMO.
Btw, that's also the case when using strict-dynamic
in frontend. A page that uses maps2 with strict-dynamic
will not be cacheable.
Is that even remotely acceptable for a static maps plugin? I don't think so.
Again, the pages are not cacheable, while host-based verification allows to cache.
So, while I understand that Google wants us to use strict-dynamic (allows them to switch backend hostnames), we should not, strict-dynamic
prevents proper caching (as it requires nonces, or hashes - but pinning externals via hashes work against the dynamic nature that is intended with strict-dynamic
) and eventually is less secure than host-based verification (also in terms of third-party host inclusion, think of EU regulations), if we can not fully trust the remote script, that we are embeddeding.
Google also knows about the strict-dynamic
problems and that this CSP rule is practically not usable for a proper system that needs caching, therefore they still (and will continue) support hostbased CSP.
Updated by Stefan Froemken 13 days ago
Hi Benjamin,
please have a look here:
This file is a core file. This handler will be called, if a CSP was protocoled, you open the CSP module and that handler explains the user what he should do. This is a recommendation on how to handle that problem.
Instead of closing this issue I would prefer to remove that line from your GoogleMapsHelper.
Updated by Benjamin Franzke 13 days ago
- Status changed from Rejected to Accepted
- Assignee set to Benjamin Franzke
I didn't read that correctly, I assumed that came from maps2, sorry. Reopening, yes we should fix that. Thanks!