Skip to content

Commit 7bd6ffc

Browse files
fred-wangmoz-wptsync-bot
authored andcommitted
Fix mistakes in Element-setAttribute-respects-Elements-node-documents-globals-CSP-after-adoption-from-non-TT-realm.html.
See #44323 (comment) Also add a more direct test for the TypeError realm. Differential Revision: https://phabricator.services.mozilla.com/D239894 bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1950626 gecko-commit: cfc415b178e0e9719e0124df703b3125d1484251 gecko-reviewers: smaug
1 parent cbd4b14 commit 7bd6ffc

File tree

2 files changed

+58
-13
lines changed

2 files changed

+58
-13
lines changed

trusted-types/Element-setAttribute-respects-Elements-node-documents-globals-CSP-after-adoption-from-non-TT-realm.html

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,22 @@
3333
async_test(
3434
(t) => {
3535
const sourceFrame = document.createElement("iframe");
36+
t.add_cleanup(() => {
37+
sourceFrame.remove();
38+
});
3639

37-
// The markup requires the parent element to ensure the attribute is associated with the
38-
// correct namespace.
39-
sourceFrame.srcdoc = passThroughPolicy.createHTML(
40+
// We cannot directly set the iframe's srcdoc otherwise its CSP
41+
// would be inherited from the main frame.
42+
// See https://w3c.github.io/webappsec-csp/#security-inherit-csp
43+
sourceFrame.src = "/common/blank.html";
44+
sourceFrame.addEventListener(
45+
"load",
46+
t.step_func_done(() => {
47+
let sourceFrameDocument = sourceFrame.contentWindow.document;
48+
sourceFrameDocument.open();
49+
// The markup requires the parent element to ensure the attribute
50+
// is associated with the correct namespace.
51+
sourceFrameDocument.write(passThroughPolicy.createHTML(
4052
`<!DOCTYPE html>
4153
<head>
4254
<meta charset="utf-8">
@@ -60,15 +72,9 @@
6072
`>
6173
doc without TT CSP.
6274
</body>`
63-
);
64-
65-
t.add_cleanup(() => {
66-
sourceFrame.remove();
67-
});
75+
));
76+
sourceFrameDocument.close();
6877

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

92+
// Sanity check: setting the attribute to a plain string does not
93+
// throw since `sourceElement`'s node document is associated to
94+
// a non-TT realm.
95+
let unsafeAttr = document.createAttributeNS(
96+
sourceAttr.namespaceURI, sourceAttr.name);
97+
unsafeAttr.value = "unsafe1";
98+
sourceElement.setAttributeNode(unsafeAttr);
99+
sourceElement.setAttributeNS(
100+
sourceAttr.namespaceURI,
101+
sourceAttr.name,
102+
"unsafe2"
103+
);
104+
86105
document.body.append(sourceElement);
87106
// Now `sourceElement`'s node document's global should belong to
88107
// a TT-realm.
@@ -92,10 +111,10 @@
92111
// invokes <https://www.w3.org/TR/trusted-types/#validate-attribute-mutation>.
93112
// The latter should throw when executing step 5.
94113

95-
assert_throws_js(sourceFrame.contentWindow.TypeError, () => {
114+
assert_throws_js(TypeError, () => {
96115
sourceElement.setAttributeNode(sourceAttr);
97116
});
98-
assert_throws_js(sourceFrame.contentWindow.TypeError, () => {
117+
assert_throws_js(TypeError, () => {
99118
sourceElement.setAttributeNS(
100119
sourceAttr.namespaceURI,
101120
sourceAttr.name,
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<!DOCTYPE html>
2+
<meta http-equiv="Content-Security-Policy"
3+
content="require-trusted-types-for 'script';"/>
4+
<link rel="help" href="https://github.com/web-platform-tests/wpt/issues/45405">
5+
<script src="/resources/testharness.js"></script>
6+
<script src="/resources/testharnessreport.js"></script>
7+
<div id="divInsertedByParser"></div>
8+
<script>
9+
test( _ => {
10+
assert_throws_js(TypeError, _ => divInsertedByParser.innerHTML = 'unsafe');
11+
}, "Setting innerHTML on a node inserted by the parser.");
12+
13+
promise_test(async t => {
14+
const iframe = document.createElement("iframe");
15+
const passThroughPolicy =
16+
trustedTypes.createPolicy("passThrough", { createHTML: s => s });
17+
iframe.srcdoc = passThroughPolicy.createHTML("<!DOCTYPE html><div></div>");
18+
await new Promise(resolve => {
19+
iframe.addEventListener("load", resolve);
20+
document.body.appendChild(iframe);
21+
});
22+
const divAdoptedFromIframe =
23+
document.adoptNode(iframe.contentDocument.body.firstElementChild);
24+
assert_throws_js(TypeError, _ => divAdoptedFromIframe.innerHTML = 'unsafe');
25+
}, "Setting innerHTML on a node adopted from a subframe.");
26+
</script>

0 commit comments

Comments
 (0)