Skip to content

Commit

Permalink
Bug 1950626 Fix mistakes in Element-setAttribute-respects-Elements-no…
Browse files Browse the repository at this point in the history
…de-documents-globals-CSP-after-adoption-from-non-TT-realm.html. r=smaug

See web-platform-tests/wpt#44323 (comment)

Also add a more direct test for the TypeError realm.

Differential Revision: https://phabricator.services.mozilla.com/D239894
  • Loading branch information
fred-wang committed Feb 28, 2025
1 parent a1b3392 commit c5663a6
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1 @@
# Bug 1950626: frame contentWindow's TypeError expected instead of window's one.
[Element-setAttribute-respects-Elements-node-documents-globals-CSP-after-adoption-from-non-TT-realm.html]
[setAttribute and setAttributeNode respect the element's node document's global's CSP;\n Element=iframe; Parent=div; Attribute=srcdoc]
expected: FAIL
[setAttribute and setAttributeNode respect the element's node document's global's CSP;\n Element=script; Parent=div; Attribute=src]
expected: FAIL

[setAttribute and setAttributeNode respect the element's node document's global's CSP;\n Element=script; Parent=svg; Attribute=href]
expected: FAIL
[setAttribute and setAttributeNode respect the element's node document's global's CSP;\n Element=script; Parent=svg; Attribute=xlink:href]
expected: FAIL
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,22 @@
async_test(
(t) => {
const sourceFrame = document.createElement("iframe");
t.add_cleanup(() => {
sourceFrame.remove();
});

// The markup requires the parent element to ensure the attribute is associated with the
// correct namespace.
sourceFrame.srcdoc = passThroughPolicy.createHTML(
// We cannot directly set the iframe's srcdoc otherwise its CSP
// would be inherited from the main frame.
// See https://w3c.github.io/webappsec-csp/#security-inherit-csp
sourceFrame.src = "/common/blank.html";
sourceFrame.addEventListener(
"load",
t.step_func_done(() => {
let sourceFrameDocument = sourceFrame.contentWindow.document;
sourceFrameDocument.open();
// The markup requires the parent element to ensure the attribute
// is associated with the correct namespace.
sourceFrameDocument.write(passThroughPolicy.createHTML(
`<!DOCTYPE html>
<head>
<meta charset="utf-8">
Expand All @@ -60,15 +72,9 @@
`>
doc without TT CSP.
</body>`
);

t.add_cleanup(() => {
sourceFrame.remove();
});
));
sourceFrameDocument.close();

sourceFrame.addEventListener(
"load",
t.step_func_done(() => {
// A window is a global object which has 1-to-1 mapping to a realm, see the first
// note of <https://html.spec.whatwg.org/#realms-settings-objects-global-objects>
// and its following paragraph. Here, `sourceElement`'s node document's global
Expand All @@ -83,6 +89,19 @@
);
sourceElement.removeAttributeNode(sourceAttr);

// Sanity check: setting the attribute to a plain string does not
// throw since `sourceElement`'s node document is associated to
// a non-TT realm.
let unsafeAttr = document.createAttributeNS(
sourceAttr.namespaceURI, sourceAttr.name);
unsafeAttr.value = "unsafe1";
sourceElement.setAttributeNode(unsafeAttr);
sourceElement.setAttributeNS(
sourceAttr.namespaceURI,
sourceAttr.name,
"unsafe2"
);

document.body.append(sourceElement);
// Now `sourceElement`'s node document's global should belong to
// a TT-realm.
Expand All @@ -92,10 +111,10 @@
// invokes <https://www.w3.org/TR/trusted-types/#validate-attribute-mutation>.
// The latter should throw when executing step 5.

assert_throws_js(sourceFrame.contentWindow.TypeError, () => {
assert_throws_js(TypeError, () => {
sourceElement.setAttributeNode(sourceAttr);
});
assert_throws_js(sourceFrame.contentWindow.TypeError, () => {
assert_throws_js(TypeError, () => {
sourceElement.setAttributeNS(
sourceAttr.namespaceURI,
sourceAttr.name,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!DOCTYPE html>
<meta http-equiv="Content-Security-Policy"
content="require-trusted-types-for 'script';"/>
<link rel="help" href="https://github.com/web-platform-tests/wpt/issues/45405">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="divInsertedByParser"></div>
<script>
test( _ => {
assert_throws_js(TypeError, _ => divInsertedByParser.innerHTML = 'unsafe');
}, "Setting innerHTML on a node inserted by the parser.");

promise_test(async t => {
const iframe = document.createElement("iframe");
const passThroughPolicy =
trustedTypes.createPolicy("passThrough", { createHTML: s => s });
iframe.srcdoc = passThroughPolicy.createHTML("<!DOCTYPE html><div></div>");
await new Promise(resolve => {
iframe.addEventListener("load", resolve);
document.body.appendChild(iframe);
});
const divAdoptedFromIframe =
document.adoptNode(iframe.contentDocument.body.firstElementChild);
assert_throws_js(TypeError, _ => divAdoptedFromIframe.innerHTML = 'unsafe');
}, "Setting innerHTML on a node adopted from a subframe.");
</script>

0 comments on commit c5663a6

Please sign in to comment.