From 081e2ec9fbdbc517f0d5ab8cd6606f0e16623df9 Mon Sep 17 00:00:00 2001 From: Mirko Brodesser <129945747+mbrodesser-Igalia@users.noreply.github.com> Date: Thu, 7 Mar 2024 15:29:13 +0100 Subject: [PATCH] Trusted Types: add tests for setAttributeNS with non-lowercase attributes with untrusted strings (#44724) * Refactor `assert_element_accepts_non_trusted_type_set_ns` to accept an element namespace and an attribute namespace * Implement the non-lowercase attribute tests --- ...-assignment-to-Element-setAttributeNS.html | 43 +++++++++++++++---- trusted-types/support/helper.sub.js | 9 ++-- 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/trusted-types/block-string-assignment-to-Element-setAttributeNS.html b/trusted-types/block-string-assignment-to-Element-setAttributeNS.html index e714de6a414390..b7f74be6b7dd22 100644 --- a/trusted-types/block-string-assignment-to-Element-setAttributeNS.html +++ b/trusted-types/block-string-assignment-to-Element-setAttributeNS.html @@ -21,13 +21,15 @@ assert_element_accepts_trusted_script_url_set_ns(window, '2', t, 'a', 'b', RESULTS.SCRIPTURL); }, "Element.setAttributeNS assigned via policy (successful ScriptURL transformation)"); + const htmlNamespace = "http://www.w3.org/1999/xhtml"; + // Unknown attributes should not be TT checked: test(t => { - assert_element_accepts_non_trusted_type_set_ns('a', 'b', 'A string', 'A string'); + assert_element_accepts_non_trusted_type_set_ns('a', 'b', 'A string', 'A string', htmlNamespace, null); }, "Element.setAttributeNS accepts untrusted string for non-specced accessor"); test(t => { - assert_element_accepts_non_trusted_type_set_ns('a', 'b', null, 'null'); + assert_element_accepts_non_trusted_type_set_ns('a', 'b', null, 'null', htmlNamespace, null); }, "Element.setAttributeNS accepts null for non-specced accessor"); // Setup trusted values for use in subsequent tests. @@ -35,26 +37,49 @@ const html = createHTML_policy(window, '6').createHTML(INPUTS.HTML); const script = createScript_policy(window, '7').createScript(INPUTS.Script); - const xlink = "http://www.w3.org/1999/xlink"; - const svg = "http://www.w3.org/2000/svg"; + const xlinkNamespace = "http://www.w3.org/1999/xlink"; + const svgNamespace = "http://www.w3.org/2000/svg"; // svg:script xlink:href=... expects a TrustedScriptURL. // Assigning a TrustedScriptURL works. test(t => { - let elem = document.createElementNS(svg, "script"); - elem.setAttributeNS(xlink, "href", script_url); + let elem = document.createElementNS(svgNamespace, "script"); + elem.setAttributeNS(xlinkNamespace, "href", script_url); assert_equals("" + RESULTS.ScriptURL, - elem.getAttributeNodeNS(xlink, "href").value); + elem.getAttributeNodeNS(xlinkNamespace, "href").value); }, "Assigning TrustedScriptURL to works"); // Assigning things that ought to not work. test(t => { - let elem = document.createElementNS(svg, "script"); + let elem = document.createElementNS(svgNamespace, "script"); const values = [ "abc", null, html, script ]; for (const v of values) { assert_throws_js(TypeError, _ => { - elem.setAttributeNS(xlink, "href", v); + elem.setAttributeNS(xlinkNamespace, "href", v); }); } }, "Blocking non-TrustedScriptURL assignment to works"); + + // . + const nonLowerCaseTests = [ + { element: "iframe", attribute: "SRCDOC", elementNamespace: htmlNamespace }, + { element: "embed", attribute: "SRC", elementNamespace: htmlNamespace }, + { element: "script", attribute: "SRC", elementNamespace: htmlNamespace }, + { element: "object", attribute: "DATA", elementNamespace: htmlNamespace }, + { element: "object", attribute: "CODEBASE", elementNamespace: htmlNamespace }, + { element: "script", attribute: "HREF", elementNamespace: svgNamespace }, + { element: "script", attribute: "HREF", elementNamespace: svgNamespace, + attributeNamespace: xlinkNamespace }, + ]; + + for (const testData of nonLowerCaseTests) { + const attributeNamespace = testData.attributeNamespace ?? null; + + test(t => { + assert_element_accepts_non_trusted_type_set_ns(testData.element, testData.attribute, "v", + "v", testData.elementNamespace, attributeNamespace); + }, "Check `setAttributeNS` allows setting non-trusted string for non-lowercase attribute \"" + + testData.attribute + "\" (ns=" + attributeNamespace + ") for \"" + testData.element + + "\" element (ns=" + testData.elementNamespace + ")."); + } diff --git a/trusted-types/support/helper.sub.js b/trusted-types/support/helper.sub.js index 219b42a8ae94cb..1775cd985c24df 100644 --- a/trusted-types/support/helper.sub.js +++ b/trusted-types/support/helper.sub.js @@ -158,9 +158,10 @@ function assert_throws_no_trusted_type_set_ns(tag, attribute, value) { }); } -function assert_element_accepts_non_trusted_type_set_ns(tag, attribute, value, expected) { - let elem = document.createElement(tag); - elem.setAttributeNS(namespace, attribute, value); - let attr_node = elem.getAttributeNodeNS(namespace, attribute); +function assert_element_accepts_non_trusted_type_set_ns(tag, attribute, value, expected, + elementNamespace, attributeNamespace) { + let elem = document.createElementNS(elementNamespace, tag); + elem.setAttributeNS(attributeNamespace, attribute, value); + let attr_node = elem.getAttributeNodeNS(attributeNamespace, attribute); assert_equals(attr_node.value + "", expected); }