1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
<!DOCTYPE html>
<title>Cross-Origin-Opener-Policy and a "javascript:" URL popup</title>
<meta charset="utf-8">
<meta name="timeout" content="long">
<meta name="variant" content="?0-3">
<meta name="variant" content="?4-7">
<meta name="variant" content="?8-11">
<meta name="variant" content="?12-15">
<meta name="variant" content="?16-last">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="/common/subset-tests.js"></script>
<script src="/common/utils.js"></script>
<script src="resources/common.js"></script>
<p>According to HTML's navigate algorithm, requests to <code>javascript:</code>
URLs should inherit the cross-origin opener policy of the active document. To
observe this, each subtest uses the following procedure.</p>
<ol>
<li>create popup with a given COOP (the <code>parentCOOP</code>)</li>
<li>navigate the popup to a <code>javascript:</code> URL (the new document is
expected to inherit the <code>parentCOOP</code>)</li>
<li>from the popup, create a second popup window with a given COOP (the
<code>childCOOP</code>)</li>
</ol>
<p>Both popup windows inspect state and report back to the test context using
BroadcastChannels.</p>
<pre>
.---- test ----.
| open(https:) |
| parentCOOP | .----- subject -------.
| '---------> | --------. |
| | | v |
| | | assign(javascript:) |
| | | (COOP under test) |
| | | | |
| | | open(https:) |
| | | childCOOP | .- child -.
| | | '--------------> | |
| | '---------------------' '---------'
| | | |
| validate | <--status---+---------------------'
'--------------'
</pre>
<script>
'use strict';
function run(t, parentCOOP, childCOOP, origin, name) {
const bc = new BroadcastChannel(name);
const childURL = encodeURIComponent(`${origin}/html/cross-origin-opener-policy/resources/coop-coep.py?coop=${childCOOP}&coep=&channel=${name}`);
open(
`/html/cross-origin-opener-policy/resources/javascript-url-same-origin.https.html` +
`?pipe=header(cross-origin-opener-policy,${parentCOOP})` +
`&childURL=${childURL}` +
`&childName=${name}`
);
t.add_cleanup(() => {
bc.postMessage('close');
});
return new Promise((resolve) => {
bc.addEventListener('message', ({data}) => {
resolve(data);
}, {once: true});
}).then(({name: childName, opener: childOpener}) => {
return new Promise((resolve) => {
bc.postMessage('inspectChild');
bc.addEventListener('message', function handle({data}) {
if (typeof data !== 'object' || !('childClosed' in data)) { return; }
bc.removeEventListener('message', handle);
resolve({
childName,
childOpener,
childClosed: data.childClosed
});
});
});
});
}
function assert_isolated(results) {
assert_equals(results.childName, '', 'child name');
assert_false(results.childOpener, 'child opener');
// The test subject's reference to the "child" window must report "closed"
// when COOP enforces isolation because the document initially created during
// the window open steps must be discarded when a new document object is
// created at the end of the navigation.
assert_true(results.childClosed, 'child closed');
}
function assert_not_isolated(results, expectedName) {
assert_equals(results.childName, expectedName, 'child name');
assert_true(results.childOpener, 'child opener');
assert_false(results.childClosed, 'child closed');
}
function run_javascript_url_tests(testArray) {
testArray.forEach(([parentCOOP, childCOOP, origin, expectation], i) => {
// Only run specified variants
if (!shouldRunSubTest(i)) {
return;
}
async_test((t) => {
const name = token();
run(t, parentCOOP, childCOOP, origin.origin, name)
.then(results => { expectation(results, name); })
.then(t.step_func_done(), t.step_func((e) => { throw e; }));
}, `navigation: ${origin.name}; ` +
`parentCOOP: ${parentCOOP}; ` +
`childCOOP: ${childCOOP}`);
});
}
const tests = [
['unsafe-none', 'unsafe-none', SAME_ORIGIN, assert_not_isolated],
['unsafe-none', 'unsafe-none', SAME_SITE, assert_not_isolated],
['unsafe-none', 'same-origin-allow-popups', SAME_ORIGIN, assert_isolated],
['unsafe-none', 'same-origin-allow-popups', SAME_SITE, assert_isolated],
['unsafe-none', 'same-origin', SAME_ORIGIN, assert_isolated],
['unsafe-none', 'same-origin', SAME_SITE, assert_isolated],
['same-origin-allow-popups', 'unsafe-none', SAME_ORIGIN, assert_not_isolated],
['same-origin-allow-popups', 'unsafe-none', SAME_SITE, assert_not_isolated],
['same-origin-allow-popups', 'same-origin-allow-popups', SAME_ORIGIN, assert_not_isolated],
['same-origin-allow-popups', 'same-origin-allow-popups', SAME_SITE, assert_isolated],
['same-origin-allow-popups', 'same-origin', SAME_ORIGIN, assert_isolated],
['same-origin-allow-popups', 'same-origin', SAME_SITE, assert_isolated],
['same-origin', 'unsafe-none', SAME_ORIGIN, assert_isolated],
['same-origin', 'unsafe-none', SAME_SITE, assert_isolated],
['same-origin', 'same-origin-allow-popups', SAME_ORIGIN, assert_isolated],
['same-origin', 'same-origin-allow-popups', SAME_SITE, assert_isolated],
['same-origin', 'same-origin', SAME_ORIGIN, assert_not_isolated],
['same-origin', 'same-origin', SAME_SITE, assert_isolated],
];
run_javascript_url_tests(tests);
</script>
|