blob: 4fa1cc587711196a6d06f61e1d178591aa0cb920 [file] [log] [blame]
<!DOCTYPE html>
<meta charset="utf-8">
<title>import() inside compiled strings uses the appropriate nonce inside a module script</title>
<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
<meta http-equiv="content-security-policy" content="script-src 'nonce-correct' 'unsafe-eval' 'unsafe-hashes' 'sha256-cAMzxBL19bKt4KwKGbxy/ZOFIIjH5AmRjlVbsD5pvNw=' 'sha256-3VjoJYNK/9HJMS8rrZHlqSZgUssDY+GPyc7AU8lNM3k='">
<script nonce="correct" src="/resources/testharness.js"></script>
<script nonce="correct" src="/resources/testharnessreport.js"></script>
<div id="dummy"></div>
<script type="module" nonce="correct">
const dummyDiv = document.querySelector("#dummy");
function createTestPromise(t) {
t.add_cleanup(() => {
delete window.evaluated_imports_a;
delete window.unreached;
delete window.continueTest;
delete window.errorTest;
});
return new Promise((resolve, reject) => {
window.unreached = t.unreached_func("Must not reach this");
window.continueTest = resolve;
window.errorTest = reject;
});
}
function assertSuccessful(module) {
assert_true(window.evaluated_imports_a, "The module must have been evaluated");
assert_equals(module.A.from, "imports-a.js", "The module namespace object must be correct");
}
promise_test(t => {
const promise = createTestPromise(t);
setTimeout(`import('../imports-a.js?label=setTimeout').then(window.continueTest, window.errorTest)`, 0);
return promise.then(assertSuccessful);
}, "setTimeout must inherit the nonce from the triggering script, thus execute");
promise_test(t => {
const promise = createTestPromise(t);
eval(`import('../imports-a.js?label=direct eval').then(window.continueTest, window.errorTest)`);
return promise.then(assertSuccessful);
}, "direct eval must inherit the nonce from the triggering script, thus execute");
promise_test(t => {
const promise = createTestPromise(t);
const evalAlias = eval;
evalAlias(`import('../imports-a.js?label=indirect eval').then(window.continueTest, window.errorTest)`);
return promise.then(assertSuccessful);
}, "indirect eval must inherit the nonce from the triggering script, thus execute");
promise_test(t => {
const promise = createTestPromise(t);
Function(`import('../imports-a.js?label=the Function constructor').then(window.continueTest, window.errorTest)`)();
return promise.then(assertSuccessful);
}, "the Function constructor must inherit the nonce from the triggering script, thus execute");
promise_test(t => {
t.add_cleanup(() => {
dummyDiv.removeAttribute("onclick");
});
const promise = createTestPromise(t);
// This only works because of the 'unsafe-hashes' and the hash in the CSP policy
dummyDiv.setAttribute(
"onclick",
`import('../imports-a.js?label=reflected inline event handlers').then(window.continueTest, window.errorTest)`
);
dummyDiv.onclick();
return promise_rejects_js(t, TypeError, promise);
}, "reflected inline event handlers must not inherit the nonce from the triggering script, thus fail");
promise_test(t => {
t.add_cleanup(() => {
dummyDiv.removeAttribute("onclick");
});
const promise = createTestPromise(t);
// This only works because of the 'unsafe-hashes' and the hash in the CSP policy
dummyDiv.setAttribute(
"onclick",
`import('../imports-a.js?label=inline event handlers triggered via UA code').then(window.continueTest, window.errorTest)`
);
assert_equals(typeof dummyDiv.onclick, 'function', "the browser must be able to parse a string containing the import() syntax into a function");
dummyDiv.click(); // different from **on**click()
return promise_rejects_js(t, TypeError, promise);
}, "inline event handlers triggered via UA code must not inherit the nonce from the triggering script, thus fail");
</script>