mirror of
https://github.com/lexmount/moli.git
synced 2026-10-19 16:01:36 +00:00
fix(trusted-types): gate execCommand HTML input
This commit is contained in:
@@ -3617,7 +3617,6 @@ trusted-types/ServiceWorkerContainer-register-from-SharedWorker.https.html
|
||||
trusted-types/TrustedType-AttributeNodes.html
|
||||
trusted-types/TrustedTypePolicyFactory-getAttributeType.html
|
||||
trusted-types/Window-TrustedTypes.html
|
||||
trusted-types/block-Document-execCommand.html
|
||||
trusted-types/block-string-assignment-to-Document-write.html
|
||||
trusted-types/block-string-assignment-to-Element-outerHTML.html
|
||||
trusted-types/block-string-assignment-to-Element-setAttribute.html
|
||||
@@ -3650,7 +3649,6 @@ trusted-types/trusted-types-event-handlers.html
|
||||
trusted-types/trusted-types-report-only.html
|
||||
trusted-types/trusted-types-reporting-check-report-DedicatedWorker-sink-mismatch.html
|
||||
trusted-types/trusted-types-reporting-for-DedicatedWorker-ServiceWorkerContainer-register.https.html
|
||||
trusted-types/trusted-types-reporting-for-Document-execCommand.html
|
||||
trusted-types/trusted-types-reporting-for-Document-write.html
|
||||
trusted-types/trusted-types-reporting-for-Element-setAttribute.html
|
||||
trusted-types/trusted-types-reporting-for-HTMLIFrameElement-srcdoc.html
|
||||
|
||||
@@ -8597,6 +8597,7 @@ trusted-types/TrustedTypePolicyFactory-getAttributeType-svg.html
|
||||
trusted-types/TrustedTypePolicyFactory-isXXX.html
|
||||
trusted-types/Window-block-eval-function-constructor.html
|
||||
trusted-types/Window-setTimeout-setInterval.html
|
||||
trusted-types/block-Document-execCommand.html
|
||||
trusted-types/block-string-assignment-to-DOMParser-parseFromString.html
|
||||
trusted-types/block-string-assignment-to-DedicatedWorker-setTimeout-setInterval.html
|
||||
trusted-types/block-string-assignment-to-Document-parseHTMLUnsafe.html
|
||||
@@ -8666,6 +8667,7 @@ trusted-types/trusted-types-reporting-for-DedicatedWorker-eval.html
|
||||
trusted-types/trusted-types-reporting-for-DedicatedWorker-function-constructor.html
|
||||
trusted-types/trusted-types-reporting-for-DedicatedWorker-importScripts.html
|
||||
trusted-types/trusted-types-reporting-for-DedicatedWorker-setTimeout-setInterval.html
|
||||
trusted-types/trusted-types-reporting-for-Document-execCommand.html
|
||||
trusted-types/trusted-types-reporting-for-Document-parseHTMLUnsafe.html
|
||||
trusted-types/trusted-types-reporting-for-Element-innerHTML.html
|
||||
trusted-types/trusted-types-reporting-for-Element-insertAdjacentHTML.html
|
||||
|
||||
@@ -537,7 +537,7 @@ pub(in crate::native_bridge) fn node_document_exec_command_callback<'s>(
|
||||
return;
|
||||
}
|
||||
EditingCommand::InsertHtml => {
|
||||
let Some(value) = editing_command_value(scope, &args) else {
|
||||
let Some(value) = editing_command_insert_html_value(scope, runtime_ptr, &args) else {
|
||||
return;
|
||||
};
|
||||
let inserted = exec_command_insert_html(scope, runtime_ptr, &value);
|
||||
@@ -759,6 +759,24 @@ fn editing_command_value<'s>(
|
||||
.map(|value| value.to_rust_string_lossy(scope))
|
||||
}
|
||||
|
||||
fn editing_command_insert_html_value<'s>(
|
||||
scope: &mut v8::PinScope<'s, '_>,
|
||||
runtime_ptr: *mut JsContextHost,
|
||||
args: &v8::FunctionCallbackArguments<'s>,
|
||||
) -> Option<String> {
|
||||
if args.length() < 3 || args.get(2).is_undefined() {
|
||||
return Some(String::new());
|
||||
}
|
||||
let requirements = unsafe { &*runtime_ptr }.trusted_types_for_script_requirements(scope);
|
||||
crate::context_bootstrap::trusted_html_string_or_throw(
|
||||
scope,
|
||||
args.get(2),
|
||||
requirements,
|
||||
"Document execCommand",
|
||||
"execCommand",
|
||||
)
|
||||
}
|
||||
|
||||
fn exec_command_insert_html(
|
||||
scope: &mut v8::PinScope<'_, '_>,
|
||||
runtime_ptr: *mut JsContextHost,
|
||||
|
||||
@@ -661,6 +661,85 @@ fn dom_parser_gates_converted_union_source_after_webidl_argument_conversion() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn document_exec_command_gates_only_insert_html_values() {
|
||||
let mut vm = new_storage_test_vm("https://exec-command-trusted-types.test/");
|
||||
vm.set_response_content_security_policies(&["require-trusted-types-for 'script'".to_owned()]);
|
||||
|
||||
let result = vm
|
||||
.eval(
|
||||
r#"
|
||||
(() => {
|
||||
const errorName = callback => {
|
||||
try {
|
||||
callback();
|
||||
return "none";
|
||||
} catch (error) {
|
||||
return error && error.name;
|
||||
}
|
||||
};
|
||||
const root = document.documentElement || document.appendChild(document.createElement("html"));
|
||||
const body = document.body || root.appendChild(document.createElement("body"));
|
||||
const input = document.createElement("input");
|
||||
body.append(input);
|
||||
input.focus();
|
||||
|
||||
const blocked = [
|
||||
errorName(() => document.execCommand("insertHTML", false, "<b>blocked</b>")),
|
||||
errorName(() => document.execCommand("InSeRtHtMl", false, null))
|
||||
];
|
||||
const unprotected = [
|
||||
errorName(() => document.execCommand("insertHTML")),
|
||||
errorName(() => document.execCommand("insertHTML", false, undefined)),
|
||||
errorName(() => document.execCommand("paste", false, "<b>plain</b>")),
|
||||
errorName(() => document.execCommand("insertText", false, "plain"))
|
||||
];
|
||||
|
||||
input.value = "";
|
||||
const custom = trustedTypes.createPolicy("exec-command-custom", {
|
||||
createHTML: value => value
|
||||
});
|
||||
const trustedReturned = document.execCommand(
|
||||
"insertHTML",
|
||||
false,
|
||||
custom.createHTML("<b>trusted</b>")
|
||||
);
|
||||
const trustedValue = input.value;
|
||||
|
||||
let sourceConversions = 0;
|
||||
const defaultCalls = [];
|
||||
trustedTypes.createPolicy("default", {
|
||||
createHTML: (value, type, sink) => {
|
||||
defaultCalls.push([value, type, sink]);
|
||||
return "<b>default</b>";
|
||||
}
|
||||
});
|
||||
input.value = "";
|
||||
const defaultReturned = document.execCommand("insertHTML", false, {
|
||||
toString() {
|
||||
sourceConversions += 1;
|
||||
return "<i>original</i>";
|
||||
}
|
||||
});
|
||||
|
||||
return JSON.stringify({
|
||||
blocked,
|
||||
unprotected,
|
||||
trusted: [trustedReturned, trustedValue],
|
||||
defaulted: [defaultReturned, input.value, sourceConversions],
|
||||
defaultCalls
|
||||
});
|
||||
})()
|
||||
"#,
|
||||
)
|
||||
.expect("Document.execCommand TrustedHTML sink probe should evaluate");
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
r#"{"blocked":["TypeError","TypeError"],"unprotected":["none","none","none","none"],"trusted":[true,"trusted"],"defaulted":[true,"default",1],"defaultCalls":[["<i>original</i>","TrustedHTML","Document execCommand"]]}"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn document_write_gates_concatenated_union_values_before_writeln_newline() {
|
||||
let mut vm = new_storage_test_vm("https://document-write-trusted-types.test/");
|
||||
|
||||
Reference in New Issue
Block a user