-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add WPT for COOP behavior in navigations to about:blank (#27548)
This CL adds a WPT test that checks the interaction of COOP same-origin-allow-popups with about:blank navigations. As discussed in whatwg/html#5198. Change-Id: Iabe461416c36468f73a41af0f69c46c545744e14 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2678150 Auto-Submit: Pâris Meuleman <pmeuleman@chromium.org> Commit-Queue: Pâris Meuleman <pmeuleman@chromium.org> Reviewed-by: Arthur Sonzogni <arthursonzogni@chromium.org> Cr-Commit-Position: refs/heads/master@{#860665} Co-authored-by: Pâris MEULEMAN <pmeuleman@chromium.org>
- Loading branch information
1 parent
2ed850a
commit c4f759f
Showing
3 changed files
with
344 additions
and
0 deletions.
There are no files selected for viewing
176 changes: 176 additions & 0 deletions
176
html/cross-origin-opener-policy/navigate-to-aboutblank.https.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
<title> | ||
This tests the inheritance of COOP for navigations to about:blank. | ||
</title> | ||
<meta name=timeout content=long> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script src="/common/get-host-info.sub.js"></script> | ||
<script src="/common/utils.js"></script> | ||
<script src="reporting/resources/dispatcher.js"></script> | ||
<script src="reporting/resources/try-access.js"></script> | ||
|
||
|
||
<p>Non-initial empty documents (about:blank) should inherit their | ||
cross-origin-opener-policy from the navigation's initiator top level document, | ||
if the initiator and its top level document are same-origin, or default | ||
(unsafe-none) otherwise. | ||
</p> | ||
|
||
<ol> | ||
<li>Create the opener popup with a given COOP <code>openerCOOP</code>.</li> | ||
<li>Add iframe to the opener popup that is either same-origin or | ||
cross-origin. | ||
</li> | ||
<li>Opener's iframe opens a new window, to a network document with <code>openeeCOOP</code>.</li> | ||
<li>Opener's iframe navigates the openee popup to about:blank.</li> | ||
</ol> | ||
|
||
<script> | ||
const directory = "/html/cross-origin-opener-policy"; | ||
const executor_path = directory + "/reporting/resources/executor.html?pipe="; | ||
const same_origin = get_host_info().HTTPS_ORIGIN; | ||
const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN; | ||
const coop_same_origin_header = | ||
'|header(Cross-Origin-Opener-Policy,same-origin)'; | ||
const coop_same_origin_allow_popups_header = | ||
'|header(Cross-Origin-Opener-Policy,same-origin-allow-popups)'; | ||
const coop_unsafe_none_header = | ||
'|header(Cross-Origin-Opener-Policy,unsafe-none)'; | ||
|
||
function navigateToAboutBlankTest( | ||
opener_COOP_header, | ||
iframe_origin, | ||
openee_COOP_header, | ||
openee_origin, | ||
expect_openee_closed | ||
){ | ||
return promise_test(async t => { | ||
const this_window_token = token(); | ||
const opener_token = token(); | ||
const openee_token = token(); | ||
const iframe_token = token(); | ||
|
||
const opener_url = same_origin + executor_path + opener_COOP_header + | ||
`&uuid=${opener_token}`; | ||
const openee_url = openee_origin + executor_path + openee_COOP_header + | ||
`&uuid=${openee_token}`; | ||
const iframe_url = iframe_origin + executor_path + `&uuid=${iframe_token}`; | ||
|
||
t.add_cleanup(() => { | ||
send(openee_token, "window.close()"); | ||
send(opener_token, "window.close()"); | ||
}); | ||
|
||
// 1. Create the opener window. | ||
let opener_window_proxy = window.open(opener_url, opener_token); | ||
|
||
// 2. Create the iframe. | ||
send(opener_token, ` | ||
iframe = document.createElement('iframe'); | ||
iframe.src = "${iframe_url}"; | ||
document.body.appendChild(iframe); | ||
`); | ||
|
||
// 3. The iframe opens its openee window. | ||
send(iframe_token, ` | ||
window.openee = window.open( | ||
'${openee_url.replace(/,/g, '\\,')}', | ||
"${openee_token}" | ||
); | ||
`); | ||
|
||
// 4. Ensure the popup is fully loaded. | ||
send(openee_token, `send("${this_window_token}", "Ack");`); | ||
assert_equals(await receive(this_window_token), "Ack"); | ||
|
||
// 5. The iframe navigates openee to about:blank. | ||
send(iframe_token, ` | ||
window.openee_blank = window.open('about:blank', "${openee_token}"); | ||
(async function() { | ||
const timeout = 2000; | ||
const retry_delay = 100; | ||
for(let i = 0; i * retry_delay < timeout; ++i) { | ||
// A try-catch block is used, because of same-origin policy, | ||
// preventing access to the document before committing about:blank. | ||
try { | ||
if (window.openee_blank.closed || | ||
window.openee_blank.document.location.href == "about:blank") { | ||
send("${this_window_token}", "about:blank loaded"); | ||
return; | ||
} | ||
} catch(e) {} | ||
await new Promise(resolve => setTimeout(resolve, retry_delay)); | ||
} | ||
send("${this_window_token}", "about:blank not loaded"); | ||
})() | ||
`); | ||
assert_equals(await receive(this_window_token), "about:blank loaded"); | ||
|
||
|
||
// 6. Retrieve and check the results. | ||
send(iframe_token, ` | ||
send("${this_window_token}", window.openee.closed); | ||
`); | ||
assert_equals(await receive(this_window_token), `${expect_openee_closed}`); | ||
}, `Navigate to about:blank from iframe with opener.top \ | ||
COOP: ${opener_COOP_header}, iframe origin: ${iframe_origin}, \ | ||
openee COOP: ${openee_COOP_header}, openee origin: ${openee_origin}.`); | ||
}; | ||
|
||
// iframe same-origin with its top-level embedder: | ||
// initial empty document and about:blank navigations initiated from the | ||
// same-origin iframe will inherit the COOP from the iframe's top-level embedder. | ||
|
||
// Since all navigations of openee are within same-origin pages with the | ||
// same COOP value, there are no browsing context group switches. | ||
navigateToAboutBlankTest( | ||
coop_same_origin_header, | ||
same_origin, | ||
coop_same_origin_header, | ||
same_origin, | ||
false | ||
); | ||
|
||
// Since all navigations of openee are within same-origin pages with the | ||
// same COOP value, there are no browsing context group switches. | ||
navigateToAboutBlankTest( | ||
coop_same_origin_allow_popups_header, | ||
same_origin, | ||
coop_same_origin_allow_popups_header, | ||
same_origin, | ||
false | ||
); | ||
|
||
// The first openee navigation, from initial empty document to | ||
// cross-origin will not switch the browsing context group, thanks to the | ||
// same-origin-allow-popups behavior. | ||
// The second openee navigation, to about:blank, will inherit from the | ||
// iniatiator's, the iframe, top. Navigating from a COOP: unsafe-none page to | ||
// a COOP: same-origin-allow-popups page causes a browsing context group | ||
// switch. | ||
navigateToAboutBlankTest( | ||
coop_same_origin_allow_popups_header, | ||
same_origin, | ||
coop_unsafe_none_header, | ||
cross_origin, | ||
true | ||
); | ||
|
||
// iframe cross-origin with its top-level embedder: | ||
// initial empty document and about:blank navigations initiated from the | ||
// cross-origin iframe will default COOP to unsafe-none. | ||
|
||
// The navigation from the initial empty document and the cross_origin url | ||
// does not cause a browsing context group switch | ||
// (both have COOP: unsafe-none). | ||
// The navigation from the cross-origin url to about:blank does not cause a | ||
// browsing context group swich, about:blank defaulted its COOP value to | ||
// unsafe-none. | ||
navigateToAboutBlankTest( | ||
coop_same_origin_allow_popups_header, | ||
cross_origin, | ||
coop_unsafe_none_header, | ||
cross_origin, | ||
false | ||
); | ||
</script> |
166 changes: 166 additions & 0 deletions
166
html/cross-origin-opener-policy/navigate-top-to-aboutblank.https.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
<title> | ||
This tests the inheritance of COOP for navigations of the top document to about:blank. | ||
</title> | ||
<meta name=timeout content=long> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script src="/common/get-host-info.sub.js"></script> | ||
<script src="/common/utils.js"></script> | ||
<script src="reporting/resources/dispatcher.js"></script> | ||
<script src="reporting/resources/try-access.js"></script> | ||
|
||
|
||
<p>Non-initial empty documents (about:blank) should inherit their | ||
cross-origin-opener-policy from the navigation's initiator top level document, | ||
if the initiator and its top level document are same-origin, or default (to | ||
unsafe-none) otherwise. | ||
</p> | ||
|
||
<ol> | ||
<li>Create the opener popup with a given COOP <code>openerCOOP</code>.</li> | ||
<li>Add iframe to the opener popup that is either same-origin or | ||
cross-origin. | ||
</li> | ||
<li>Opener opens a new window, to a network document with the same origin and | ||
COOP value as opener.</li> | ||
<li>Opener's iframe navigates its parent frame (opener) to about:blank.</li> | ||
<li>Verify the openee still has access to its opener.</li> | ||
</ol> | ||
|
||
<script> | ||
const directory = "/html/cross-origin-opener-policy"; | ||
const executor_path = directory + "/reporting/resources/executor.html?pipe="; | ||
const same_origin = get_host_info().HTTPS_ORIGIN; | ||
const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN; | ||
const coop_same_origin_header = | ||
'|header(Cross-Origin-Opener-Policy,same-origin)'; | ||
const coop_same_origin_allow_popups_header = | ||
'|header(Cross-Origin-Opener-Policy,same-origin-allow-popups)'; | ||
const coop_unsafe_none_header = | ||
'|header(Cross-Origin-Opener-Policy,unsafe-none)'; | ||
|
||
function navigateToAboutBlankTest( | ||
COOP_header, | ||
iframe_origin, | ||
expect_opener_closed | ||
){ | ||
return promise_test(async t => { | ||
const this_window_token = token(); | ||
const opener_token = token(); | ||
const openee_token = token(); | ||
const iframe_token = token(); | ||
|
||
const opener_url = same_origin + executor_path + COOP_header + | ||
`&uuid=${opener_token}`; | ||
const openee_url = same_origin + executor_path + COOP_header + | ||
`&uuid=${openee_token}`; | ||
const iframe_url = iframe_origin + executor_path + `&uuid=${iframe_token}`; | ||
|
||
t.add_cleanup(() => { | ||
send(opener_token, "window.close()"); | ||
send(openee_token, "window.close()"); | ||
}); | ||
|
||
// 1. Create the opener window. | ||
let opener_window_proxy = window.open(opener_url, opener_token); | ||
|
||
// 2. Create the iframe. | ||
// The allow-top-navigation sandbox flags disables the intervention | ||
// requiring a user gesture to navigate top. | ||
send(opener_token, ` | ||
iframe = document.createElement('iframe'); | ||
iframe.src = "${iframe_url}"; | ||
iframe.sandbox = "allow-top-navigation allow-scripts"; | ||
document.body.appendChild(iframe); | ||
`); | ||
|
||
// 3. The opener opens openee window. | ||
send(opener_token, ` | ||
window.openee = window.open( | ||
'${openee_url.replace(/,/g, '\\,')}' | ||
); | ||
`); | ||
|
||
// 4. Ensure the popup is fully loaded. | ||
send(openee_token, `send("${this_window_token}", "Ack");`); | ||
assert_equals(await receive(this_window_token), "Ack"); | ||
|
||
// 5. The iframe navigates its top-level document to about:blank. | ||
send(iframe_token, ` | ||
top.location.href = "about:blank"; | ||
`); | ||
|
||
// 6. Ensure opener is fully loaded and then retrieve the results. | ||
send(openee_token, ` | ||
(async function() { | ||
const timeout = 2000; | ||
const retry_delay = 100; | ||
for(let i = 0; i * retry_delay < timeout; ++i) { | ||
// A try-catch block is used, because of same-origin policy, | ||
// which may prevent the access to the opener if its origin changed, | ||
// after a navigation to about:blank from the cross origin iframe. | ||
try { | ||
if ( | ||
window.opener === null || | ||
window.opener.closed || | ||
window.opener.document.location.href == "about:blank") { | ||
send("${this_window_token}", "about:blank loaded"); | ||
return; | ||
} | ||
} catch(e) { | ||
// The exception is thrown when about:blank is loaded and is | ||
// cross-origin with openee. | ||
send("${this_window_token}", "about:blank loaded"); | ||
return; | ||
} | ||
await new Promise(resolve => setTimeout(resolve, retry_delay)); | ||
} | ||
send("${this_window_token}", "about:blank NOT loaded"); | ||
})() | ||
`); | ||
assert_equals(await receive(this_window_token), "about:blank loaded"); | ||
|
||
// 7. Retrieve and check the results. | ||
send(openee_token, ` | ||
send( | ||
"${this_window_token}", | ||
window.opener === null || window.opener.closed); | ||
`); | ||
|
||
assert_equals(await receive(this_window_token), `${expect_opener_closed}`); | ||
}, `Navigate top to about:blank from iframe with \ | ||
opener COOP: ${COOP_header}, iframe origin: ${iframe_origin}`); | ||
}; | ||
|
||
// iframe same-origin with its top-level embedder: | ||
// initial empty document and about:blank navigations initiated from the | ||
// same-origin iframe will inherit COOP from the iframe's top-level embedder. | ||
|
||
// Opener's navigation to about:blank stays in the same browsing context group. | ||
navigateToAboutBlankTest( | ||
coop_same_origin_header, | ||
same_origin, | ||
false | ||
); | ||
|
||
// iframe cross-origin with its top-level embedder: | ||
// initial empty document and about:blank navigations initiated from the | ||
// cross-origin iframe will default COOP to unsafe-none. | ||
|
||
// Opener's navigation to about:blank doesn't inherit COOP, leading to a | ||
// browsing context group switch. | ||
navigateToAboutBlankTest( | ||
coop_same_origin_header, | ||
cross_origin, | ||
true | ||
); | ||
|
||
// Same origin allow popups allows the navigation of top to the cross-origin | ||
// about:blank (origin inherited from the iframe) page, which does not have COOP | ||
// (initiator is a cross origin iframe). | ||
navigateToAboutBlankTest( | ||
coop_same_origin_allow_popups_header, | ||
cross_origin, | ||
false | ||
); | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters