Created attachment 470205 [details] HTML file the demonstrates the bug Steps to reproduce the problem: 1. Set Content-Security-Header script-src to include a nonce value along with strict-dynamic (either via web server or http-equiv meta tag) 2. Add a script tag with a valid nonce value and `data-foo="<script>"` (i.e. attribute value of <script> with the < and > html-escaped. 3. Try to load the file. Example html file attached. What is the expected behavior? Script loads. What went wrong? CSP blocks loading with this message in the console: Refused to load https://s4.bcbits.com/bundle/bundle/1/head-c13a053f90fe799f77dee956c87a57f7.js because it does not appear in the script-src directive of the Content Security Policy. Did this work before? Yes. I'm not sure the exact version when this bug first appeared, but it was definitely working in the latest version of Safari as of Sep 16, 2021 when the issue was first reported in Chrome. Works as expected in Firefox. This has been a problem in Chrome for a long time, but this is a new regression in Safari. Here is the equivalent bug for Chrome: https://issues.chromium.org/issues/40791912 This smells like an heuristic XSS-protection to prevent <script> being injected into script data attributes, but it's overzealous when the attribute value is correctly escaped like in this example.
This was probably still working fine in Safari as of June 7, 2023 (according to some chatter in our internal work Slack).
<rdar://problem/124228938>
https://w3c.github.io/webappsec-csp/#is-element-nonceable says: - If attribute’s value contains an ASCII case-insensitive match for "<script" or "<style", return "Not Nonceable". Testing in Firefox, I also get a CSP error: Content-Security-Policy: The page's settings blocked the loading of a resource at https://s4.bcbits.com/bundle/bundle/1/head-c13a053f90fe799f77dee956c87a57f7.js ("script-src"). It seems that Chrome, Firefox and Safari are all aligned here. AIUI, though this is somewhat overzealous, implementations are aligned with the spec, the attribute value is computed by unescaping the characters. To make progress on this, it seems that we should go to the spec and change/clarify the intent. CCing @Anne, if he has thoughts on this. Marking as INVALID for now, we can reopen or create a new bug after hearing from CSP spec editors.
Given that the purpose of "6.7.3.1. Is element nonceable?" is to prevent nonce hijacking (https://w3c.github.io/webappsec-csp/#security-nonce-hijacking), only unescaped "<script" would indicate such an attack. It would be great if the spec could account for this as there are legitimate use cases (e.g. passing template data into scripts for use with `document.currentScript`, though, granted, that's less useful nowadays with <script type="module">). That said, I can confirm that Firefox is also blocking this markup now. With all three major browsers now aligned on the behavior, I understand if this edge case is not worth supporting.
Daniel, the moment CSP looks at the attribute the knowledge of whether the developer typed < or < is lost. And preserving that would not be worth the effort.