Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test for importing a srcdoc attribute node from a non-TT realm to a TT iframe element throws #44323

Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
http-equiv="Content-Security-Policy"
content="require-trusted-types-for 'script';"
/>
<title>
trusted-types (TT): `setAttribute`/`setAttributeNode` for an element
adopted from a non-TT realm respects TT's Content-Security-Policy (CSP)
</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div id="nonSVGTestElements">
<iframe srcdoc="v"></iframe>
<embed src="v" />
<script src="v"></script>
<object data="v"></object>
<object codebase="v"></object>
</div>
<svg id="svgTestElements">
<script href="v"></script>
<script xlink:href="v"></script>
</svg>
<script>
const passThroughPolicy = trustedTypes.createPolicy("passThrough", {
createHTML: (s) => s,
});

function runTest(aTestElement) {
const testAttr = aTestElement.attributes[0];

async_test(
(t) => {
const sourceFrame = document.createElement("iframe");

// The markup requires the parent element to ensure the attribute is associated with the
// correct namespace.
sourceFrame.srcdoc = passThroughPolicy.createHTML(
`<!DOCTYPE html>
<head>
<meta charset="utf-8">
</head>
<body>
<` +
aTestElement.parentElement.localName +
`>
<` +
aTestElement.localName +
` ` +
testAttr.name +
`="` +
testAttr.value +
`">
</` +
aTestElement.localName +
`>
</` +
aTestElement.parentElement.localName +
`>
doc without TT CSP.
</body>`
);

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

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
// belongs to a non-TT realm.

const sourceElement =
sourceFrame.contentDocument.body.querySelector(
aTestElement.localName
);
const sourceAttr = sourceElement.getAttributeNode(
testAttr.name
);
sourceElement.removeAttributeNode(sourceAttr);

document.body.append(sourceElement);
// Now `sourceElement`'s node document's global belongs to a TT-realm.

assert_throws_js(sourceFrame.contentWindow.TypeError, () => {
sourceElement.setAttributeNode(sourceAttr);
mbrodesser-Igalia marked this conversation as resolved.
Show resolved Hide resolved
});
assert_throws_js(sourceFrame.contentWindow.TypeError, () => {
sourceElement.setAttributeNS(
sourceAttr.namespaceURI,
sourceAttr.name,
sourceAttr.value
);
});
})
);

document.body.append(sourceFrame);
},
`setAttribute and setAttributeNode respect the element's node document's global's CSP;
Element=${aTestElement.localName}; Parent=${aTestElement.parentElement.localName}; Attribute=${testAttr.name}`
);
}

for (const testElement of document.querySelectorAll(
"#nonSVGTestElements *"
)) {
runTest(testElement);
}

for (const testElement of document.querySelectorAll(
"#svgTestElements *"
)) {
runTest(testElement);
}
</script>
</body>
</html>