Implement Trusted Types enforcement for scripts
Categories
(Core :: DOM: Security, task)
Tracking
()
| Tracking | Status | |
|---|---|---|
| firefox144 | --- | fixed |
People
(Reporter: fwang, Assigned: fwang)
References
Details
(Whiteboard: [domsecurity-active])
Attachments
(6 files, 1 obsolete file)
See https://w3c.github.io/trusted-types/dist/spec/#enforcement-in-scripts.
In bug 1905706, I'm just going to make the IDL arguments Trusted Types but the spec has more things e.g. booleans for "trusted" and "changed by trusted sink" and when they are set. See also https://github.com/w3c/trusted-types/issues/525 and https://searchfox.org/mozilla-central/rev/e74b86533c2499eb6393071aeedcfb080d84e4da/testing/web-platform/tests/trusted-types/HTMLScriptElement-internal-slot.html#125,134
https://github.com/w3c/trusted-types/pull/533#discussion_r1835791151 might need clarification before implementing this.
| Assignee | ||
Comment 2•1 year ago
|
||
We also need a similar mechanism for SVG script element, but it's not in the spec yet: https://github.com/w3c/trusted-types/issues/483
| Assignee | ||
Comment 3•1 year ago
|
||
The tests are badly written. I submitted:
https://github.com/web-platform-tests/wpt/pull/50824
https://github.com/web-platform-tests/wpt/pull/50861
The spec is being edited at https://github.com/w3c/trusted-types/pull/581
| Assignee | ||
Updated•1 year ago
|
| Assignee | ||
Updated•1 year ago
|
| Assignee | ||
Comment 4•1 year ago
|
||
Luke had commented the implementation would be easier with https://github.com/w3c/trusted-types/pull/579 so I will give it a try.
| Assignee | ||
Comment 5•1 year ago
|
||
| Assignee | ||
Comment 6•1 year ago
|
||
Updated•1 year ago
|
| Assignee | ||
Comment 7•1 year ago
|
||
| Assignee | ||
Comment 8•1 year ago
|
||
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
| Assignee | ||
Comment 9•1 year ago
|
||
| Assignee | ||
Comment 10•1 year ago
|
||
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
| Assignee | ||
Updated•1 year ago
|
Comment 11•1 year ago
|
||
Updated•1 year ago
|
Comment 12•1 year ago
|
||
Comment 13•1 year ago
|
||
Backed out for causing macOS build bustages on nsMenuGroupOwnerX.mm
Comment 14•1 year ago
|
||
| Assignee | ||
Updated•1 year ago
|
Comment 15•1 year ago
|
||
| bugherder | ||
Updated•1 year ago
|
Updated•11 months ago
|
Updated•11 months ago
|
Updated•11 months ago
|
| Assignee | ||
Comment 16•11 months ago
|
||
This is a testcase trying to set innerText/textContent on a script via
HTMLElement.prototype.__lookupSetter__("innerText").call(scriptElement, ...)
Node.prototype.__lookupSetter__("textContent").call(scriptElement, ...)
In WebKit, this is always causing a TT security violation.
In Chromium, it is only causing a TT security violation if the specified text is untrusted. And if it is trusted, the script runs normally.
| Assignee | ||
Comment 17•11 months ago
|
||
(In reply to Frédéric Wang (:fredw) from comment #16)
In WebKit, this is always causing a TT security violation.
In Chromium, it is only causing a TT security violation if the specified text is untrusted. And if it is trusted, the script runs normally.
After some checks & discussions, WebKit's behavior is the one aligned with the spec here. I'm adding new tests here: https://github.com/web-platform-tests/wpt/pull/54548
Updated•11 months ago
|
Updated•11 months ago
|
Updated•11 months ago
|
Updated•11 months ago
|
Updated•11 months ago
|
Updated•11 months ago
|
| Assignee | ||
Comment 18•11 months ago
|
||
Comment 19•11 months ago
|
||
Comment 20•11 months ago
|
||
| bugherder | ||
| Assignee | ||
Updated•11 months ago
|
Updated•11 months ago
|
Comment 21•11 months ago
|
||
Can I please confirm what this delivers, because it isn't simple for me to read the code.
From the title I assume that this adds support for Content-Security-Policy: require-trusted-types-for right?
Presumably enabled behind the same preference as the trusted types used in API?
| Assignee | ||
Comment 22•11 months ago
|
||
It's indeed behind the TrustedTypes flag.
Support for require-trusted-types-for 'script' was implemented in previous patches. This CSP rule basically just enables Trusted Types checks so that things like
let script = document.createElement("script");
script.text = "/* arbitrary JS code */";
would cause a security violation (or run the default policy on the JS string, if such a policy defined) when we try to set the script text.
Other APIs that can be used to set the script's text, but they don't necessarily run a the Trusted Type check. The patch in this bug implements adds such a check when the script is about to be executed i.e.
let script = document.createElement("script");
script.appendChild(document.createTextNode("/* arbitrary JS code */"));
document.body.appendChild(script);
would cause a security violation (or again, run the default policy) when we append the script to the document.
Comment 23•11 months ago
|
||
Thanks Fred.
So in the first case I can avoid a security violation by passing a TrustedScript or having a default policy - right?
let script = document.createElement("script");
script.text = someTrustedType; // A TrustedScript
In the second case for which this patch exists is there a way OTHER than using a default policy to pass a trusted type to the document.createTextNode()?
My assumption is "no" based on https://w3c.github.io/trusted-types/dist/spec/#enforcement-in-scripts - which seems to indicate that the recommended way to set the content is the one shown above.
| Assignee | ||
Comment 24•11 months ago
|
||
(In reply to Hamish Willee from comment #23)
Thanks Fred.
So in the first case I can avoid a security violation by passing a
TrustedScriptor having a default policy - right?let script = document.createElement("script"); script.text = someTrustedType; // A TrustedScriptIn the second case for which this patch exists is there a way OTHER than using a default policy to pass a trusted type to the
document.createTextNode()?My assumption is "no" based on https://w3c.github.io/trusted-types/dist/spec/#enforcement-in-scripts - which seems to indicate that the recommended way to set the content is the one shown above.
You are right, and there is no way to pass a TrustedScript in the second case, this is mainly to prevent attacker to bypass the trusted type check via the many alternative means of setting the script text. However, someone could still do something like
script.text = mypolicy.createScript(script.text) // create a TrustedScript
to ensure script text is trusted before appending the script. But I'm not sure that's really useful in practice.
And just to be clear, there are many ways to set the script text (see https://wpt.fyi/results/trusted-types/script-enforcement-001.html for example) and multiple of them can be combined. The TT check is only run when the script is about to run (so when document.body.appendChild(script); is called in the example) or immediately if you use a TrustedScript sink like script.text, script.textContent or script.innerText.
(Note sure it's worth documenting, but one subtle thing is that script.innerHTML is a TrustedHTML sink so it will run the TT check to make sure the content is trusted HTML but that does not guarantee it is a TrustedScript)
Updated•11 months ago
|
Description
•