Automatic update from web-platform-tests [LNA] remove check for initiator being in the frame tree of the navigating frame. This check was originally introduced in crrev.com/c/6763697 to only allow LNA permission prompts to trigger within a single tab/context. However, crbug.com/491509051 details a valid scenario where the initiator of a subframe navigation is not in the frame tree of the subframe being navigated. Specifically, this happens when: * top window (origin1) iframes origin2 * iframe of origin2 opens a new window, also to origin2 * new window of origin2 does `opener.location.href = <LNA-url>` With this fix, this scenario ends up checking the LNA permission on the initiator, which may pop up the permission prompt on the initiator window. This was chosen as it is the initiator which is triggering the LNA navigation. One quirk here: if instead of the opened window initiating the navigation, if instead it posted a message to the iframe that triggered the iframe to navigate itself, then the permission check would be on the iframe. This might lead to slightly different behaviour depending on permission policy settings, but is not a permissions bypass as the LNA permission is still required from an initiator in either case. Bug: 491509051 Change-Id: Iac1b4ded1459a61a93b9a6fdaf8278db529bf50b Cq-Do-Not-Cancel-Tryjobs: true Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7681373 Reviewed-by: Camille Lamy <clamy@chromium.org> Commit-Queue: Hubert Chao <hchao@chromium.org> Reviewed-by: Chris Thompson <cthomp@chromium.org> Cr-Commit-Position: refs/heads/main@{#1612807} -- wpt-commits: de7735f191cc51bc58e0dd56ca024277aab34dc1 wpt-pr: 59092
109 lines
4.1 KiB
HTML
109 lines
4.1 KiB
HTML
<!DOCTYPE html>
|
|
<meta charset="utf-8">
|
|
<title>LNA Opener navigation tests </title>
|
|
<body>
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="/resources/testdriver.js"></script>
|
|
<script src="/resources/testdriver-vendor.js"></script>
|
|
<script src="resources/support.sub.js"></script>
|
|
<script>
|
|
"use strict";
|
|
|
|
// These tests are testing the following scenario
|
|
//
|
|
// --------------------------
|
|
// | window (origin1) |
|
|
// | | |
|
|
// | \ |
|
|
// | iframe (origin2) |
|
|
// | |
|
|
// |-------------------------
|
|
//
|
|
// * javascript in the iframe (origin2) executes "open(origin2)".
|
|
// * new window opened then executes a LNA navigation through
|
|
//
|
|
// opener.location.href = "lna-url"
|
|
//
|
|
// In this scenario, the permission to be checked is on the initiator, which
|
|
// is the new window.
|
|
|
|
promise_test(t => {
|
|
const navigateUrl = resolveUrl("resources/openee.html",
|
|
sourceResolveOptions({ server: Server.HTTP_LOOPBACK }));
|
|
const iframeUrl = resolveUrl("resources/iframe-opener.html",
|
|
sourceResolveOptions({
|
|
server: Server.HTTPS_PUBLIC,
|
|
permissionName: 'loopback-network',
|
|
permissionValue: 'granted'}));
|
|
iframeUrl.searchParams.set('mode', 'iframe');
|
|
iframeUrl.searchParams.set('navigateto', navigateUrl.toString());
|
|
|
|
// Top window is an HTTP url; the top window need a separate origin from the
|
|
// iframe and there is only one public-address-space HTTPS origin available.
|
|
//
|
|
// Permissions set to denied as these permissions should not be checked,
|
|
// denying lets us fail the load if they are checked.
|
|
const sourceUrl = resolveUrl("resources/iframer.html",
|
|
sourceResolveOptions({
|
|
server: Server.HTTP_PUBLIC,
|
|
permissionName: 'loopback-network',
|
|
permissionValue: 'denied'}));
|
|
sourceUrl.searchParams.set('url', iframeUrl);
|
|
|
|
function checkResult(evt) {
|
|
assert_equals(evt.data.message, "loaded");
|
|
t.done();
|
|
}
|
|
|
|
const promise = new Promise((resolve) => {
|
|
window.addEventListener('message', resolve, {once: true});
|
|
}).then(checkResult);
|
|
const popup = window.open(sourceUrl);
|
|
t.add_cleanup(() => popup.close());
|
|
|
|
return promise;
|
|
}, 'LNA Public to loopback navigate iframe from opener with permission');
|
|
|
|
promise_test(t => {
|
|
const navigateUrl = resolveUrl("resources/openee.html",
|
|
sourceResolveOptions({ server: Server.HTTP_LOOPBACK }));
|
|
const iframeUrl = resolveUrl("resources/iframe-opener.html",
|
|
sourceResolveOptions({
|
|
server: Server.HTTPS_PUBLIC,
|
|
permissionName: 'loopback-network',
|
|
permissionValue: 'denied'}));
|
|
iframeUrl.searchParams.set('mode', 'iframe');
|
|
iframeUrl.searchParams.set('navigateto', navigateUrl.toString());
|
|
|
|
// Top window is an HTTP url; the top window need a separate origin from the
|
|
// iframe and there is only one public-address-space HTTPS origin available.
|
|
//
|
|
// Permissions set to denied as these permissions should not be checked,
|
|
// granting lets us fail the test if they are checked.
|
|
const sourceUrl = resolveUrl("resources/iframer.html",
|
|
sourceResolveOptions({
|
|
server: Server.HTTP_PUBLIC,
|
|
permissionName: 'loopback-network',
|
|
permissionValue: 'granted'}));
|
|
sourceUrl.searchParams.set('url', iframeUrl);
|
|
|
|
const popup = window.open(sourceUrl);
|
|
t.add_cleanup(() => popup.close());
|
|
// Frame should not load because navigation should be blocked.
|
|
//
|
|
// There exists no interoperable way to check whether an iframe failed to
|
|
// load, so we use a timeout.
|
|
// See: https://github.com/whatwg/html/issues/125
|
|
return Promise.race([
|
|
futureMessage().then((data) => data.message),
|
|
new Promise((resolve) => {
|
|
t.step_timeout(() => resolve('timeout'), 2000 /* ms */);
|
|
}),
|
|
]).then((message) => assert_equals(message, "timeout"));
|
|
|
|
}, 'LNA Public to loopback navigate iframe from opener without permission');
|
|
|
|
</script>
|
|
</body>
|