Bug 270588 - REGRESSION (Safari 17?): Script tag with valid CSP nonce fails to load with escaped <script> in an attribute value
Summary: REGRESSION (Safari 17?): Script tag with valid CSP nonce fails to load with e...
Status: RESOLVED INVALID
Alias: None
Product: WebKit
Classification: Unclassified
Component: Page Loading (show other bugs)
Version: Safari Technology Preview
Hardware: Mac (Apple Silicon) macOS 14
: P2 Normal
Assignee: Nobody
URL:
Keywords: BrowserCompat, InRadar
Depends on:
Blocks:
 
Reported: 2024-03-06 11:38 PST by Daniel Dickison
Modified: 2024-03-25 04:26 PDT (History)
8 users (show)

See Also:


Attachments
HTML file the demonstrates the bug (493 bytes, text/html)
2024-03-06 11:38 PST, Daniel Dickison
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Daniel Dickison 2024-03-06 11:38:07 PST
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="&lt;script&gt;"` (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.
Comment 1 Daniel Dickison 2024-03-06 11:40:53 PST
This was probably still working fine in Safari as of June 7, 2023 (according to some chatter in our internal work Slack).
Comment 2 Radar WebKit Bug Importer 2024-03-07 13:11:52 PST
<rdar://problem/124228938>
Comment 3 youenn fablet 2024-03-25 02:55:15 PDT
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.
Comment 4 Daniel Dickison 2024-03-25 04:26:23 PDT
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.
Comment 5 Anne van Kesteren 2024-03-25 04:34:34 PDT
Daniel, the moment CSP looks at the attribute the knowledge of whether the developer typed &lt; or < is lost. And preserving that would not be worth the effort.