Skip to content

Commit ebc8da9

Browse files
fred-wangmoz-wptsync-bot
authored andcommitted
Add more Trusted Type tests for HTML/SVG script enforcements.
Differential Revision: https://phabricator.services.mozilla.com/D251094 bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1968383 gecko-commit: 5966d24c9bcd7c9db515424651b59428a41e1c22 gecko-reviewers: smaug
1 parent 4420f22 commit ebc8da9

8 files changed

+1670
-0
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2+
<html xmlns="http://www.w3.org/1999/xhtml">
3+
<head>
4+
<script src="/resources/testharness.js"></script>
5+
<script src="/resources/testharnessreport.js"></script>
6+
<script src="support/namespaces.js"></script>
7+
<script src="support/passthroughpolicy.js"></script>
8+
<script src="support/script-messages.js"></script>
9+
<link rel="help" href="https://w3c.github.io/trusted-types/dist/spec/#enforcement-in-scripts"/>
10+
<meta http-equiv="Content-Security-Policy" content="require-trusted-types-for 'script';"/>
11+
</head>
12+
<body>
13+
<!--- See script-enforcement-001.html an explanation of this test.
14+
The HTML parser won't create a child element for the span child of
15+
scriptForOuterHTMLTest below, so we instead rely on the XHTML parser. -->
16+
<div>
17+
<script id="scriptForOuterHTMLTest" type="unknown"><span></span></script>
18+
</div>
19+
<div id="container"></div>
20+
<script>
21+
promise_test(async t => {
22+
await promise_rejects_js(t, TypeError, script_messages_for(_ => {
23+
document.createElement("script").outerHTML = LOG_RUN_MESSAGE;
24+
}), "TrustedHTML required.");
25+
await no_script_message_for(_ => {
26+
let script = document.getElementById("scriptForOuterHTMLTest");
27+
script.remove();
28+
script.removeAttribute("type");
29+
script.firstElementChild.outerHTML = passthroughpolicy.createHTML(LOG_RUN_MESSAGE);
30+
document.getElementById("container").appendChild(script);
31+
});
32+
}, "Script source set via TrustedHTML sink Element.outerHTML drops trustworthiness.");
33+
</script>
34+
</body>
35+
</html>
Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
<!DOCTYPE html>
2+
<script src="/resources/testharness.js"></script>
3+
<script src="/resources/testharnessreport.js"></script>
4+
<script src="support/namespaces.js"></script>
5+
<script src="support/passthroughpolicy.js"></script>
6+
<script src="support/script-messages.js"></script>
7+
<link rel="help" href="https://w3c.github.io/trusted-types/dist/spec/#enforcement-in-scripts">
8+
<meta http-equiv="Content-Security-Policy" content="require-trusted-types-for 'script';">
9+
<!-- This test modifies the source of a new (initially disconnected)
10+
HTMLScriptElement by various DOM APIs and verifies whether it will
11+
remain trustworthy. This can be done by checking whether the script
12+
is actually executed after insertion, because this page enforces
13+
Trusted Types without defining any default policy. -->
14+
<div id="container"></div>
15+
<script>
16+
promise_test(async t => {
17+
let message = await script_message_for(_ => {
18+
let script = create_html_script_with_trusted_source_text(LOG_RUN_MESSAGE);
19+
container.appendChild(script);
20+
});
21+
assert_equals(message, "RUN");
22+
}, "The HTMLScriptElement is initially trusted.");
23+
24+
promise_test(async t => {
25+
await promise_rejects_js(t, TypeError, script_messages_for(_ => {
26+
document.createElement("script").innerText = LOG_RUN_MESSAGE;
27+
}), "TrustedScript required.");
28+
let message = await script_message_for(_ => {
29+
let script = document.createElement("script");
30+
script.innerText = passthroughpolicy.createScript(LOG_RUN_MESSAGE);
31+
container.appendChild(script);
32+
});
33+
assert_equals(message, "RUN");
34+
}, "Script source set via TrustedScript sink HTMLScriptElement.innerText keeps trustworthiness.");
35+
36+
promise_test(async t => {
37+
await promise_rejects_js(t, TypeError, script_messages_for(_ => {
38+
document.createElement("script").textContent = LOG_RUN_MESSAGE;
39+
}), "TrustedScript required.");
40+
let message = await script_message_for(_ => {
41+
let script = document.createElement("script");
42+
script.textContent = passthroughpolicy.createScript(LOG_RUN_MESSAGE);
43+
container.appendChild(script);
44+
});
45+
assert_equals(message, "RUN");
46+
}, "Script source set via TrustedScript sink HTMLScriptElement.textContent keeps trustworthiness.");
47+
48+
promise_test(async t => {
49+
await promise_rejects_js(t, TypeError, script_messages_for(_ => {
50+
document.createElement("script").text = LOG_RUN_MESSAGE;
51+
}), "TrustedScript required.");
52+
let message = await script_message_for(_ => {
53+
let script = document.createElement("script");
54+
script.text = passthroughpolicy.createScript(LOG_RUN_MESSAGE);
55+
container.appendChild(script);
56+
});
57+
assert_equals(message, "RUN");
58+
}, "Script source set via TrustedScript sink HTMLScriptElement.text keeps trustworthiness.");
59+
60+
promise_test(async t => {
61+
await promise_rejects_js(t, TypeError, script_messages_for(_ => {
62+
document.createElement("script").innerHTML = LOG_RUN_MESSAGE;
63+
}), "TrustedHTML required.");
64+
await no_script_message_for(_ => {
65+
let script = document.createElement("script");
66+
script.innerHTML = passthroughpolicy.createHTML(LOG_RUN_MESSAGE);
67+
container.appendChild(script);
68+
});
69+
}, "Script source set via TrustedHTML sink Element.innerHTML drops trustworthiness.");
70+
71+
promise_test(async t => {
72+
await promise_rejects_js(t, TypeError, script_messages_for(_ => {
73+
document.createElement("script").setHTMLUnsafe(LOG_RUN_MESSAGE);
74+
}), "TrustedHTML required.");
75+
await no_script_message_for(_ => {
76+
let script = document.createElement("script");
77+
script.setHTMLUnsafe(passthroughpolicy.createHTML(LOG_RUN_MESSAGE));
78+
container.appendChild(script);
79+
});
80+
}, "Script source set via TrustedHTML sink Element.setHTMLUnsafe() drops trustworthiness.");
81+
82+
if (HTMLScriptElement.prototype.setHTML) {
83+
promise_test(async t => {
84+
// https://wicg.github.io/sanitizer-api/#set-and-filter-html
85+
let script = document.createElement("script");
86+
script.setHTML(LOG_RUN_MESSAGE);
87+
assert_equals(script.text, "");
88+
}, "Script source cannot be set via Element.setHTML().");
89+
}
90+
91+
promise_test(async t => {
92+
let message = await script_message_for(_ => {
93+
let script = create_html_script_with_trusted_source_text(`${LOG_RUN_MESSAGE};;;`);
94+
script.firstChild.splitText(3);
95+
container.appendChild(script);
96+
});
97+
assert_equals(message, "RUN");
98+
}, "Splitting script source via Text.splitText() keeps trustworthiness.");
99+
100+
promise_test(async t => {
101+
let message = await script_message_for(_ => {
102+
let script = create_html_script_with_trusted_source_text(`${LOG_RUN_MESSAGE};;;`);
103+
script.firstChild.splitText(3);
104+
script.normalize();
105+
container.appendChild(script);
106+
});
107+
assert_equals(message, "RUN");
108+
}, "Normalizing script source via Element.normalize() keeps trustworthiness.");
109+
110+
promise_test(async t => {
111+
await no_script_message_for(_ => {
112+
let script = create_html_script_with_trusted_source_text(";");
113+
script.firstChild.nodeValue = LOG_RUN_MESSAGE;
114+
container.appendChild(script);
115+
});
116+
}, "Script source set via Node.nodeValue drops trustworthiness.");
117+
118+
promise_test(async t => {
119+
await no_script_message_for(_ => {
120+
let script = create_html_script_with_trusted_source_text(";");
121+
script.firstChild.data = LOG_RUN_MESSAGE;
122+
container.appendChild(script);
123+
});
124+
}, "Setting script source via CharacterData.data drops trustworthiness.");
125+
126+
promise_test(async t => {
127+
await no_script_message_for(_ => {
128+
let script = create_html_script_with_trusted_source_text(";");
129+
script.firstChild.appendData(LOG_RUN_MESSAGE);
130+
container.appendChild(script);
131+
});
132+
}, "Setting script source via CharacterData.appendData() drops trustworthiness.");
133+
134+
promise_test(async t => {
135+
await no_script_message_for(_ => {
136+
let script = create_html_script_with_trusted_source_text(";");
137+
script.firstChild.insertData(0, LOG_RUN_MESSAGE);
138+
container.appendChild(script);
139+
});
140+
}, "Setting script source via CharacterData.insertData() drops trustworthiness.");
141+
142+
promise_test(async t => {
143+
await no_script_message_for(_ => {
144+
let script = create_html_script_with_trusted_source_text(";");
145+
script.firstChild.replaceData(0, 0, LOG_RUN_MESSAGE);
146+
container.appendChild(script);
147+
});
148+
}, "Setting script source via CharacterData.replaceData() drops trustworthiness.");
149+
150+
promise_test(async t => {
151+
await no_script_message_for(_ => {
152+
let script = create_html_script_with_trusted_source_text(`//${LOG_RUN_MESSAGE}`);
153+
script.firstChild.deleteData(0, 2);
154+
container.appendChild(script);
155+
});
156+
}, "Setting script source via CharacterData.deleteData() drops trustworthiness.");
157+
158+
promise_test(async t => {
159+
await no_script_message_for(_ => {
160+
let script = create_html_script_with_trusted_source_text(";");
161+
script.firstChild.before(LOG_RUN_MESSAGE);
162+
container.appendChild(script);
163+
});
164+
}, "Setting script source via CharacterData.before() drops trustworthiness.");
165+
166+
promise_test(async t => {
167+
await no_script_message_for(_ => {
168+
let script = create_html_script_with_trusted_source_text(";");
169+
script.firstChild.after(LOG_RUN_MESSAGE);
170+
container.appendChild(script);
171+
});
172+
}, "Setting script source via CharacterData.after() drops trustworthiness.");
173+
174+
promise_test(async t => {
175+
await no_script_message_for(_ => {
176+
let script = create_html_script_with_trusted_source_text(`;;;${LOG_RUN_MESSAGE}`);
177+
script.firstChild.splitText(3);
178+
script.firstChild.remove();
179+
container.appendChild(script);
180+
});
181+
}, "Setting script source via CharacterData.remove() drops trustworthiness.");
182+
183+
promise_test(async t => {
184+
await no_script_message_for(_ => {
185+
let script = create_html_script_with_trusted_source_text(";");
186+
script.firstChild.replaceWith(document.createTextNode(LOG_RUN_MESSAGE));
187+
container.appendChild(script);
188+
});
189+
}, "Setting script source via CharacterData.replaceWith() drops trustworthiness.");
190+
191+
promise_test(async t => {
192+
await no_script_message_for(_ => {
193+
let script = create_html_script_with_trusted_source_text(";");
194+
script.appendChild(document.createTextNode(LOG_RUN_MESSAGE));
195+
container.appendChild(script);
196+
});
197+
}, "Setting script source via Node.appendChild() drops trustworthiness.");
198+
199+
promise_test(async t => {
200+
await no_script_message_for(_ => {
201+
let script = create_html_script_with_trusted_source_text(";");
202+
script.insertBefore(document.createTextNode(LOG_RUN_MESSAGE), script.firstChild);
203+
container.appendChild(script);
204+
});
205+
}, "Setting script source via Node.insertBefore() drops trustworthiness.");
206+
207+
promise_test(async t => {
208+
await no_script_message_for(_ => {
209+
let script = create_html_script_with_trusted_source_text(";");
210+
script.replaceChild(document.createTextNode(LOG_RUN_MESSAGE), script.firstChild);
211+
container.appendChild(script);
212+
});
213+
}, "Setting script source via Node.replaceChild() drops trustworthiness.");
214+
215+
promise_test(async t => {
216+
await no_script_message_for(_ => {
217+
let script = create_html_script_with_trusted_source_text(`;;;${LOG_RUN_MESSAGE}`);
218+
script.firstChild.splitText(3);
219+
script.removeChild(script.firstChild);
220+
container.appendChild(script);
221+
});
222+
}, "Setting script source via Node.removeChild() drops trustworthiness.");
223+
224+
promise_test(async t => {
225+
await no_script_message_for(_ => {
226+
let script = create_html_script_with_trusted_source_text(";");
227+
script.prepend(document.createTextNode(LOG_RUN_MESSAGE));
228+
container.appendChild(script);
229+
});
230+
}, "Setting script source via Element.prepend() drops trustworthiness.");
231+
232+
promise_test(async t => {
233+
await no_script_message_for(_ => {
234+
let script = create_html_script_with_trusted_source_text(";");
235+
script.append(document.createTextNode(LOG_RUN_MESSAGE));
236+
container.appendChild(script);
237+
});
238+
}, "Setting script source via Element.append() drops trustworthiness.");
239+
240+
promise_test(async t => {
241+
await no_script_message_for(_ => {
242+
let script = create_html_script_with_trusted_source_text(";");
243+
script.replaceChildren(document.createTextNode(LOG_RUN_MESSAGE));
244+
container.appendChild(script);
245+
});
246+
}, "Setting script source via Element.replaceChildren() drops trustworthiness.");
247+
248+
promise_test(async t => {
249+
await no_script_message_for(_ => {
250+
let script = create_html_script_with_trusted_source_text(";");
251+
script.moveBefore(document.createTextNode(LOG_RUN_MESSAGE), script.firstChild);
252+
container.appendChild(script);
253+
});
254+
}, "Setting script source via Element.moveBefore() drops trustworthiness.");
255+
256+
promise_test(async t => {
257+
await promise_rejects_js(t, TypeError, script_messages_for(_ => {
258+
document.createElement("script").insertAdjacentHTML("afterbegin", LOG_RUN_MESSAGE);
259+
}), "TrustedHTML required.");
260+
await no_script_message_for(_ => {
261+
let script = create_html_script_with_trusted_source_text(";");
262+
script.insertAdjacentHTML("afterbegin", passthroughpolicy.createHTML(LOG_RUN_MESSAGE));
263+
container.appendChild(script);
264+
});
265+
await no_script_message_for(_ => {
266+
let script = create_html_script_with_trusted_source_text(";");
267+
script.insertAdjacentHTML("beforeend", passthroughpolicy.createHTML(LOG_RUN_MESSAGE));
268+
container.appendChild(script);
269+
});
270+
}, "Setting script source via TrustedHTML sink Node.insertAdjacentHTML() drops trustworthiness.");
271+
272+
promise_test(async t => {
273+
await no_script_message_for(_ => {
274+
let script = create_html_script_with_trusted_source_text(";");
275+
script.insertAdjacentText("afterbegin", LOG_RUN_MESSAGE);
276+
container.appendChild(script);
277+
});
278+
await no_script_message_for(_ => {
279+
let script = create_html_script_with_trusted_source_text(";");
280+
script.insertAdjacentText("beforeend", LOG_RUN_MESSAGE);
281+
container.appendChild(script);
282+
});
283+
}, "Setting script source via Node.insertAdjacentText() drops trustworthiness.");
284+
285+
promise_test(async t => {
286+
await no_script_message_for(_ => {
287+
let script = create_html_script_with_trusted_source_text(`;`);
288+
let range = new Range();
289+
range.selectNode(script.firstChild);
290+
range.insertNode(document.createTextNode(LOG_RUN_MESSAGE));
291+
container.appendChild(script);
292+
});
293+
}, "Setting script source via Range.insertNode() drops trustworthiness.");
294+
295+
promise_test(async t => {
296+
await no_script_message_for(_ => {
297+
let script = create_html_script_with_trusted_source_text(`//;;;${LOG_RUN_MESSAGE}`);
298+
script.firstChild.splitText(2);
299+
let range = new Range();
300+
range.setStart(script.firstChild, 0);
301+
range.setEnd(script.lastChild, 3);
302+
range.deleteContents();
303+
container.appendChild(script);
304+
});
305+
}, "Setting script source via Range.deleteContents() drops trustworthiness.");
306+
307+
promise_test(async t => {
308+
await no_script_message_for(_ => {
309+
let script = create_html_script_with_trusted_source_text(`${LOG_RUN_MESSAGE}`);
310+
let clone = script.cloneNode(true);
311+
container.appendChild(clone);
312+
});
313+
}, "Cloning a script via Node.cloneNode() drops trustworthiness.");
314+
315+
promise_test(async t => {
316+
await no_script_message_for(_ => {
317+
let div = document.createElement("div");
318+
let script = create_html_script_with_trusted_source_text(`${LOG_RUN_MESSAGE}`);
319+
div.appendChild(script);
320+
let range = new Range();
321+
range.selectNode(script);
322+
let documentFragment = range.cloneContents();
323+
container.appendChild(documentFragment.firstElementChild);
324+
});
325+
}, "Cloning a script via Range.cloneContents() drops trustworthiness.");
326+
</script>
327+
</body>

0 commit comments

Comments
 (0)