Avoid crash when non-trusted-script object is passed into Function constructor (#39451)

It is possible to pass in objects that are not trusted scripts into the
Function constructor. Rather than crashing, we now treat these as
untrusted. `can_compile_string_with_trusted_type` doesn't need to know
the contents of a string, as it always marks it as untrusted.

We can make the same optimization in the string case, where we no longer
need to convert the string.

Testing: This change adds a WPT crash test.
Fixes #39436

Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
This commit is contained in:
Tim van der Lippe 2025-09-26 20:33:56 +02:00 committed by GitHub
parent d29ad5b9c3
commit b38bf3e606
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 34 additions and 4 deletions

View file

@ -552,13 +552,16 @@ unsafe extern "C" fn content_security_policy_allows(
parameter_args_vec parameter_args_vec
.push(TrustedScriptOrString::TrustedScript(trusted_script)); .push(TrustedScriptOrString::TrustedScript(trusted_script));
} else { } else {
unreachable!(); // It's not a trusted script but a different object. Treat it
// as if it is a string, since we don't need the actual contents
// of the object.
parameter_args_vec
.push(TrustedScriptOrString::String(DOMString::new()));
} }
} else if value.is_string() { } else if value.is_string() {
let string_ptr = std::ptr::NonNull::new(value.to_string()).unwrap(); // We don't need to know the specific string, only that it is untrusted
let dom_string = unsafe { jsstr_to_string(*cx, string_ptr) };
parameter_args_vec parameter_args_vec
.push(TrustedScriptOrString::String(dom_string.into())); .push(TrustedScriptOrString::String(DOMString::new()));
} else { } else {
unreachable!(); unreachable!();
} }

View file

@ -836283,6 +836283,13 @@
{} {}
] ]
], ],
"eval-with-non-trusted-script-object.html": [
"455e2620afc496b438e3a221451f260097146349",
[
null,
{}
]
],
"eval-with-permissive-csp.html": [ "eval-with-permissive-csp.html": [
"b3dc352017675a2634aa96ac1fdea01b55ce9243", "b3dc352017675a2634aa96ac1fdea01b55ce9243",
[ [

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<script nonce="abc" src="/resources/testharness.js"></script>
<script nonce="abc" src="/resources/testharnessreport.js"></script>
<script nonce="abc" src="support/helper.sub.js"></script>
<!-- Note: Trusted Types enforcement, and a CSP that does not blanket-allow eval. -->
<meta http-equiv="Content-Security-Policy" content="script-src 'nonce-abc'; require-trusted-types-for 'script'">
</head>
<body>
<script nonce="abc">
const p = createScript_policy(window, 1);
test(t => {
assert_throws_js(EvalError, _ => {
// Without Trusted Types enforcement, this would return 47
new Function({toString() { return "a"; }}, "return a + 42")(5);
});
}, "Function constructor of stringified object and TrustedScript fails.");
</script>