mirror of
https://github.com/servo/servo.git
synced 2025-09-17 10:28:22 +01:00
Add trusted type checks for eval arguments (#39263)
Also bumps mozjs to the latest version that has support for `GStackVector` which is what this callback uses. Part of #36258 Fixes #38877 Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
This commit is contained in:
parent
033da09800
commit
d1c3e5f58f
9 changed files with 97 additions and 185 deletions
8
Cargo.lock
generated
8
Cargo.lock
generated
|
@ -1643,7 +1643,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "content-security-policy"
|
||||
version = "0.5.4"
|
||||
source = "git+https://github.com/servo/rust-content-security-policy?branch=servo-csp#b437ae2001616161ce4729b49408e7785b2f6960"
|
||||
source = "git+https://github.com/servo/rust-content-security-policy?branch=servo-csp#7b7bbb54905f44fb6b001fcd4d7ad45503c2e664"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bitflags 2.9.4",
|
||||
|
@ -5349,7 +5349,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "mozjs"
|
||||
version = "0.14.1"
|
||||
source = "git+https://github.com/servo/mozjs#af903e0fc6f634699a8a7fc021adcbb3389beefd"
|
||||
source = "git+https://github.com/servo/mozjs#ae642f8cd3d2b462b40b99a11da06df9912ecc2c"
|
||||
dependencies = [
|
||||
"bindgen 0.71.1",
|
||||
"cc",
|
||||
|
@ -5361,8 +5361,8 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "mozjs_sys"
|
||||
version = "0.140.0-1"
|
||||
source = "git+https://github.com/servo/mozjs#af903e0fc6f634699a8a7fc021adcbb3389beefd"
|
||||
version = "0.140.0-3"
|
||||
source = "git+https://github.com/servo/mozjs#ae642f8cd3d2b462b40b99a11da06df9912ecc2c"
|
||||
dependencies = [
|
||||
"bindgen 0.71.1",
|
||||
"cargo_metadata",
|
||||
|
|
|
@ -72,9 +72,9 @@ impl TrustedScript {
|
|||
global: &GlobalScope,
|
||||
code_string: DOMString,
|
||||
compilation_type: CompilationType,
|
||||
_parameter_strings: u8, // FIXME in bindings generation
|
||||
parameter_strings: Vec<DOMString>,
|
||||
body_string: DOMString,
|
||||
_parameter_args: u8, // FIXME in bindings generation
|
||||
parameter_args: Vec<TrustedScriptOrString>,
|
||||
body_arg: HandleValue,
|
||||
can_gc: CanGc,
|
||||
) -> bool {
|
||||
|
@ -87,7 +87,7 @@ impl TrustedScript {
|
|||
};
|
||||
// Step 2.2. Let isTrusted be true if bodyArg implements TrustedScript,
|
||||
// and false otherwise.
|
||||
let is_trusted = match TrustedTypePolicyFactory::is_trusted_script(cx, body_arg) {
|
||||
let mut is_trusted = match TrustedTypePolicyFactory::is_trusted_script(cx, body_arg) {
|
||||
// Step 2.3. If isTrusted is true then:
|
||||
Ok(trusted_script) => {
|
||||
// Step 2.3.1. If bodyString is not equal to bodyArg’s data, set isTrusted to false.
|
||||
|
@ -96,13 +96,28 @@ impl TrustedScript {
|
|||
_ => false,
|
||||
};
|
||||
// Step 2.4. If isTrusted is true, then:
|
||||
// Step 2.4.1. Assert: parameterArgs’ [list/size=] is equal to [parameterStrings]' size.
|
||||
// Step 2.4.2. For each index of the range 0 to |parameterArgs]' [list/size=]:
|
||||
// Step 2.4.2.1. Let arg be parameterArgs[index].
|
||||
// Step 2.4.2.2. If arg implements TrustedScript, then:
|
||||
// Step 2.4.2.2.1. if parameterStrings[index] is not equal to arg’s data,
|
||||
// set isTrusted to false.
|
||||
// Step 2.4.2.3. Otherwise, set isTrusted to false.
|
||||
if is_trusted {
|
||||
// Step 2.4.1. Assert: parameterArgs’ [list/size=] is equal to [parameterStrings]' size.
|
||||
assert!(parameter_args.len() == parameter_strings.len());
|
||||
// Step 2.4.2. For each index of the range 0 to |parameterArgs]' [list/size=]:
|
||||
for index in 0..parameter_args.len() {
|
||||
// Step 2.4.2.1. Let arg be parameterArgs[index].
|
||||
match ¶meter_args[index] {
|
||||
// Step 2.4.2.2. If arg implements TrustedScript, then:
|
||||
TrustedScriptOrString::TrustedScript(trusted_script) => {
|
||||
// Step 2.4.2.2.1. if parameterStrings[index] is not equal to arg’s data,
|
||||
// set isTrusted to false.
|
||||
if parameter_strings[index] != trusted_script.data() {
|
||||
is_trusted = false;
|
||||
}
|
||||
},
|
||||
// Step 2.4.2.3. Otherwise, set isTrusted to false.
|
||||
TrustedScriptOrString::String(_) => {
|
||||
is_trusted = false;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
// Step 2.5. Let sourceToValidate be a new TrustedScript object created in realm
|
||||
// whose data is set to codeString if isTrusted is true, and codeString otherwise.
|
||||
let source_string = if is_trusted {
|
||||
|
|
|
@ -20,6 +20,7 @@ use std::{os, ptr, thread};
|
|||
|
||||
use background_hang_monitor_api::ScriptHangAnnotation;
|
||||
use js::conversions::jsstr_to_string;
|
||||
use js::gc::StackGCVector;
|
||||
use js::glue::{
|
||||
CollectServoSizes, CreateJobQueue, DeleteJobQueue, DispatchablePointer, DispatchableRun,
|
||||
JS_GetReservedSlot, JobQueueTraps, RUST_js_GetErrorMessage, SetBuildId, SetUpEventLoopDispatch,
|
||||
|
@ -29,19 +30,19 @@ use js::glue::{
|
|||
use js::jsapi::{
|
||||
AsmJSOption, BuildIdCharVector, CompilationType, ContextOptionsRef,
|
||||
Dispatchable_MaybeShuttingDown, GCDescription, GCOptions, GCProgress, GCReason,
|
||||
GetPromiseUserInputEventHandlingState, HandleObject, HandleString,
|
||||
GetPromiseUserInputEventHandlingState, Handle as RawHandle, HandleObject, HandleString,
|
||||
HandleValue as RawHandleValue, Heap, InitConsumeStreamCallback, JS_AddExtraGCRootsTracer,
|
||||
JS_InitDestroyPrincipalsCallback, JS_InitReadPrincipalsCallback, JS_NewObject,
|
||||
JS_NewStringCopyN, JS_SetGCCallback, JS_SetGCParameter, JS_SetGlobalJitCompilerOption,
|
||||
JS_SetOffthreadIonCompilationEnabled, JS_SetReservedSlot, JS_SetSecurityCallbacks,
|
||||
JSCLASS_RESERVED_SLOTS_MASK, JSCLASS_RESERVED_SLOTS_SHIFT, JSClass, JSClassOps,
|
||||
JSContext as RawJSContext, JSGCParamKey, JSGCStatus, JSJitCompilerOption, JSObject,
|
||||
JSSecurityCallbacks, JSTracer, JobQueue, MimeType, MutableHandleObject, MutableHandleString,
|
||||
PromiseRejectionHandlingState, PromiseUserInputEventHandlingState, RuntimeCode,
|
||||
SetDOMCallbacks, SetGCSliceCallback, SetJobQueue, SetPreserveWrapperCallbacks,
|
||||
JSSecurityCallbacks, JSString, JSTracer, JobQueue, MimeType, MutableHandleObject,
|
||||
MutableHandleString, PromiseRejectionHandlingState, PromiseUserInputEventHandlingState,
|
||||
RuntimeCode, SetDOMCallbacks, SetGCSliceCallback, SetJobQueue, SetPreserveWrapperCallbacks,
|
||||
SetProcessBuildIdOp, SetPromiseRejectionTrackerCallback, StreamConsumer as JSStreamConsumer,
|
||||
};
|
||||
use js::jsval::{ObjectValue, UndefinedValue};
|
||||
use js::jsval::{JSVal, ObjectValue, UndefinedValue};
|
||||
use js::panic::wrap_panic;
|
||||
pub(crate) use js::rust::ThreadSafeJSContext;
|
||||
use js::rust::wrappers::{GetPromiseIsHandled, JS_GetPromiseResult};
|
||||
|
@ -62,6 +63,7 @@ use crate::body::BodyMixin;
|
|||
use crate::dom::bindings::codegen::Bindings::PromiseBinding::PromiseJobCallback;
|
||||
use crate::dom::bindings::codegen::Bindings::ResponseBinding::Response_Binding::ResponseMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::ResponseBinding::ResponseType as DOMResponseType;
|
||||
use crate::dom::bindings::codegen::UnionTypes::TrustedScriptOrString;
|
||||
use crate::dom::bindings::conversions::{
|
||||
get_dom_class, private_from_object, root_from_handleobject, root_from_object,
|
||||
};
|
||||
|
@ -504,9 +506,9 @@ unsafe extern "C" fn content_security_policy_allows(
|
|||
runtime_code: RuntimeCode,
|
||||
code_string: HandleString,
|
||||
compilation_type: CompilationType,
|
||||
parameter_strings: u8, // FIXME in bindings generation
|
||||
parameter_strings: RawHandle<StackGCVector<*mut JSString>>,
|
||||
body_string: HandleString,
|
||||
parameter_args: u8, // FIXME in bindings generation
|
||||
parameter_args: RawHandle<StackGCVector<JSVal>>,
|
||||
body_arg: RawHandleValue,
|
||||
can_compile_strings: *mut bool,
|
||||
) -> bool {
|
||||
|
@ -516,21 +518,66 @@ unsafe extern "C" fn content_security_policy_allows(
|
|||
// SpiderMonkey provides null pointer when executing webassembly.
|
||||
let in_realm_proof = AlreadyInRealm::assert_for_cx(cx);
|
||||
let global = &GlobalScope::from_context(*cx, InRealm::Already(&in_realm_proof));
|
||||
let csp_list = global.get_csp_list();
|
||||
|
||||
allowed = match runtime_code {
|
||||
RuntimeCode::JS => TrustedScript::can_compile_string_with_trusted_type(
|
||||
cx,
|
||||
global,
|
||||
safely_convert_null_to_string(cx, code_string),
|
||||
compilation_type,
|
||||
parameter_strings,
|
||||
safely_convert_null_to_string(cx, body_string),
|
||||
parameter_args,
|
||||
HandleValue::from_raw(body_arg),
|
||||
CanGc::note(),
|
||||
),
|
||||
RuntimeCode::WASM => global.get_csp_list().is_wasm_evaluation_allowed(global),
|
||||
};
|
||||
// If we don't have any CSP checks to run, short-circuit all logic here
|
||||
allowed = csp_list.is_none() ||
|
||||
match runtime_code {
|
||||
RuntimeCode::JS => {
|
||||
let parameter_strings = Handle::from_raw(parameter_strings);
|
||||
let parameter_strings_length = parameter_strings.len();
|
||||
let mut parameter_strings_vec =
|
||||
Vec::with_capacity(parameter_strings_length as usize);
|
||||
|
||||
for i in 0..parameter_strings_length {
|
||||
let Some(str_) = parameter_strings.at(i) else {
|
||||
unreachable!();
|
||||
};
|
||||
parameter_strings_vec.push(safely_convert_null_to_string(cx, str_.into()));
|
||||
}
|
||||
|
||||
let parameter_args = Handle::from_raw(parameter_args);
|
||||
let parameter_args_length = parameter_args.len();
|
||||
let mut parameter_args_vec = Vec::with_capacity(parameter_args_length as usize);
|
||||
|
||||
for i in 0..parameter_args_length {
|
||||
let Some(arg) = parameter_args.at(i) else {
|
||||
unreachable!();
|
||||
};
|
||||
let value = arg.into_handle().get();
|
||||
if value.is_object() {
|
||||
if let Ok(trusted_script) =
|
||||
root_from_object::<TrustedScript>(value.to_object(), *cx)
|
||||
{
|
||||
parameter_args_vec
|
||||
.push(TrustedScriptOrString::TrustedScript(trusted_script));
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
} else if value.is_string() {
|
||||
let string_ptr = std::ptr::NonNull::new(value.to_string()).unwrap();
|
||||
let dom_string = unsafe { jsstr_to_string(*cx, string_ptr) };
|
||||
parameter_args_vec
|
||||
.push(TrustedScriptOrString::String(dom_string.into()));
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
||||
TrustedScript::can_compile_string_with_trusted_type(
|
||||
cx,
|
||||
global,
|
||||
safely_convert_null_to_string(cx, code_string),
|
||||
compilation_type,
|
||||
parameter_strings_vec,
|
||||
safely_convert_null_to_string(cx, body_string),
|
||||
parameter_args_vec,
|
||||
HandleValue::from_raw(body_arg),
|
||||
CanGc::note(),
|
||||
)
|
||||
},
|
||||
RuntimeCode::WASM => global.get_csp_list().is_wasm_evaluation_allowed(global),
|
||||
};
|
||||
});
|
||||
*can_compile_strings = allowed;
|
||||
true
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
[report-clips-sample.https.html]
|
||||
[Function constructor - the other kind of eval - is clipped.]
|
||||
expected: FAIL
|
||||
|
||||
[Async Function constructor is also clipped.]
|
||||
expected: FAIL
|
||||
|
||||
[Generator Function constructor is also clipped.]
|
||||
expected: FAIL
|
||||
|
||||
[AsyncGenerator Function constructor is also clipped.]
|
||||
expected: FAIL
|
|
@ -1,3 +0,0 @@
|
|||
[eval-csp-tt-no-default-policy.html]
|
||||
[Function constructor of string and TrustedScript fails.]
|
||||
expected: FAIL
|
|
@ -1,18 +0,0 @@
|
|||
[eval-function-constructor-untrusted-arguments-and-applying-default-policy.html]
|
||||
[plain string at index 0 (default policy modifying the function text).]
|
||||
expected: FAIL
|
||||
|
||||
[plain string at index 1 (default policy modifying the function text).]
|
||||
expected: FAIL
|
||||
|
||||
[plain string at index 2 (default policy modifying the function text).]
|
||||
expected: FAIL
|
||||
|
||||
[TrustedScript with forged toString() at index 0 (default policy modifying the function text).]
|
||||
expected: FAIL
|
||||
|
||||
[TrustedScript with forged toString() at index 1 (default policy modifying the function text).]
|
||||
expected: FAIL
|
||||
|
||||
[TrustedScript with forged toString() at index 2 (default policy modifying the function text).]
|
||||
expected: FAIL
|
|
@ -1,93 +0,0 @@
|
|||
[eval-function-constructor.html]
|
||||
[Function constructor with mixed plain and trusted strings, mask #8]
|
||||
expected: FAIL
|
||||
|
||||
[AsyncFunction constructor with mixed plain and trusted strings, mask #8]
|
||||
expected: FAIL
|
||||
|
||||
[GeneratorFunction constructor with mixed plain and trusted strings, mask #8]
|
||||
expected: FAIL
|
||||
|
||||
[AsyncGeneratorFunction constructor with mixed plain and trusted strings, mask #8]
|
||||
expected: FAIL
|
||||
|
||||
[Function constructor with mixed plain and trusted strings, mask #9]
|
||||
expected: FAIL
|
||||
|
||||
[AsyncFunction constructor with mixed plain and trusted strings, mask #9]
|
||||
expected: FAIL
|
||||
|
||||
[GeneratorFunction constructor with mixed plain and trusted strings, mask #9]
|
||||
expected: FAIL
|
||||
|
||||
[AsyncGeneratorFunction constructor with mixed plain and trusted strings, mask #9]
|
||||
expected: FAIL
|
||||
|
||||
[Function constructor with mixed plain and trusted strings, mask #10]
|
||||
expected: FAIL
|
||||
|
||||
[AsyncFunction constructor with mixed plain and trusted strings, mask #10]
|
||||
expected: FAIL
|
||||
|
||||
[GeneratorFunction constructor with mixed plain and trusted strings, mask #10]
|
||||
expected: FAIL
|
||||
|
||||
[AsyncGeneratorFunction constructor with mixed plain and trusted strings, mask #10]
|
||||
expected: FAIL
|
||||
|
||||
[Function constructor with mixed plain and trusted strings, mask #11]
|
||||
expected: FAIL
|
||||
|
||||
[AsyncFunction constructor with mixed plain and trusted strings, mask #11]
|
||||
expected: FAIL
|
||||
|
||||
[GeneratorFunction constructor with mixed plain and trusted strings, mask #11]
|
||||
expected: FAIL
|
||||
|
||||
[AsyncGeneratorFunction constructor with mixed plain and trusted strings, mask #11]
|
||||
expected: FAIL
|
||||
|
||||
[Function constructor with mixed plain and trusted strings, mask #12]
|
||||
expected: FAIL
|
||||
|
||||
[AsyncFunction constructor with mixed plain and trusted strings, mask #12]
|
||||
expected: FAIL
|
||||
|
||||
[GeneratorFunction constructor with mixed plain and trusted strings, mask #12]
|
||||
expected: FAIL
|
||||
|
||||
[AsyncGeneratorFunction constructor with mixed plain and trusted strings, mask #12]
|
||||
expected: FAIL
|
||||
|
||||
[Function constructor with mixed plain and trusted strings, mask #13]
|
||||
expected: FAIL
|
||||
|
||||
[AsyncFunction constructor with mixed plain and trusted strings, mask #13]
|
||||
expected: FAIL
|
||||
|
||||
[GeneratorFunction constructor with mixed plain and trusted strings, mask #13]
|
||||
expected: FAIL
|
||||
|
||||
[AsyncGeneratorFunction constructor with mixed plain and trusted strings, mask #13]
|
||||
expected: FAIL
|
||||
|
||||
[Function constructor with mixed plain and trusted strings, mask #14]
|
||||
expected: FAIL
|
||||
|
||||
[AsyncFunction constructor with mixed plain and trusted strings, mask #14]
|
||||
expected: FAIL
|
||||
|
||||
[GeneratorFunction constructor with mixed plain and trusted strings, mask #14]
|
||||
expected: FAIL
|
||||
|
||||
[AsyncGeneratorFunction constructor with mixed plain and trusted strings, mask #14]
|
||||
expected: FAIL
|
||||
|
||||
[Function constructor with trusted strings, and a forged toString() for the one at index 0]
|
||||
expected: FAIL
|
||||
|
||||
[Function constructor with trusted strings, and a forged toString() for the one at index 1]
|
||||
expected: FAIL
|
||||
|
||||
[Function constructor with trusted strings, and a forged toString() for the one at index 2]
|
||||
expected: FAIL
|
|
@ -1,12 +0,0 @@
|
|||
[trusted-types-reporting-for-DedicatedWorker-function-constructor.html]
|
||||
[Violation report for Function with plain string.]
|
||||
expected: FAIL
|
||||
|
||||
[Violation report for AsyncFunction with plain string.]
|
||||
expected: FAIL
|
||||
|
||||
[Violation report for GeneratorFunction with plain string.]
|
||||
expected: FAIL
|
||||
|
||||
[Violation report for AsyncGeneratorFunction with plain string.]
|
||||
expected: FAIL
|
|
@ -1,12 +0,0 @@
|
|||
[trusted-types-reporting-for-Window-function-constructor.html]
|
||||
[Violation report for Function with plain string.]
|
||||
expected: FAIL
|
||||
|
||||
[Violation report for AsyncFunction with plain string.]
|
||||
expected: FAIL
|
||||
|
||||
[Violation report for GeneratorFunction with plain string.]
|
||||
expected: FAIL
|
||||
|
||||
[Violation report for AsyncGeneratorFunction with plain string.]
|
||||
expected: FAIL
|
Loading…
Add table
Add a link
Reference in a new issue