Bug 1867824 [wpt PR 43476] - [Private Network Access] Add anchor navigation wpts, a=testonly

Automatic update from web-platform-tests
[Private Network Access] Add anchor navigation wpts

This is very similar to the window-open tests but they open new windows
via an anchor link click.

Bug: 1291252
Change-Id: I93108369d7fc9e9cc5dae10ec06a009bd84064a8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5053884
Commit-Queue: Jonathan Hao <phao@chromium.org>
Reviewed-by: Yifan Luo <lyf@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1231997}

--

wpt-commits: 866a3036c79d1e8b651ae1d1375eace93b9ea920
wpt-pr: 43476
This commit is contained in:
Jonathan Hao 2023-12-02 10:04:30 +00:00 коммит произвёл moz-wptsync-bot
Родитель d39f7aff14
Коммит 77b8dd13ed
6 изменённых файлов: 356 добавлений и 30 удалений

Просмотреть файл

@ -0,0 +1,190 @@
// META: script=/common/subset-tests-by-key.js
// META: script=/common/dispatcher/dispatcher.js
// META: script=/common/utils.js
// META: script=resources/support.sub.js
// META: variant=?include=from-local
// META: variant=?include=from-private
// META: variant=?include=from-public
// META: variant=?include=from-treat-as-public
//
// These tests verify that secure contexts can navigate to less-public address
// spaces via an anchor link iff the target server responds affirmatively to
// preflight requests.
setup(() => {
assert_true(window.isSecureContext);
});
// Source: secure local context.
//
// All fetches unaffected by Private Network Access.
subsetTestByKey("from-local", promise_test_parallel, t => anchorTest(t, {
source: { server: Server.HTTPS_LOCAL },
target: { server: Server.HTTPS_LOCAL },
expected: NavigationTestResult.SUCCESS,
}), "local to local: no preflight required.");
subsetTestByKey("from-local", promise_test_parallel, t => anchorTest(t, {
source: { server: Server.HTTPS_LOCAL },
target: { server: Server.HTTPS_PRIVATE },
expected: NavigationTestResult.SUCCESS,
}), "local to private: no preflight required.");
subsetTestByKey("from-local", promise_test_parallel, t => anchorTest(t, {
source: { server: Server.HTTPS_LOCAL },
target: { server: Server.HTTPS_PUBLIC },
expected: NavigationTestResult.SUCCESS,
}), "local to public: no preflight required.");
// Generates tests of preflight behavior for a single (source, target) pair.
//
// Scenarios:
//
// - preflight response has non-2xx HTTP code
// - preflight response is missing CORS headers
// - preflight response is missing the PNA-specific `Access-Control` header
// - success
//
function makePreflightTests({
key,
sourceName,
sourceServer,
sourceTreatAsPublic,
targetName,
targetServer,
}) {
const prefix =
`${sourceName} to ${targetName}: `;
const source = {
server: sourceServer,
treatAsPublic: sourceTreatAsPublic,
};
promise_test_parallel(t => anchorTest(t, {
source,
target: {
server: targetServer,
behavior: { preflight: PreflightBehavior.failure() },
},
expected: NavigationTestResult.FAILURE,
}), prefix + "failed preflight.");
promise_test_parallel(t => anchorTest(t, {
source,
target: {
server: targetServer,
behavior: { preflight: PreflightBehavior.noCorsHeader(token()) },
},
expected: NavigationTestResult.FAILURE,
}), prefix + "missing CORS headers.");
promise_test_parallel(t => anchorTest(t, {
source,
target: {
server: targetServer,
behavior: { preflight: PreflightBehavior.noPnaHeader(token()) },
},
expected: NavigationTestResult.FAILURE,
}), prefix + "missing PNA header.");
promise_test_parallel(t => anchorTest(t, {
source,
target: {
server: targetServer,
behavior: { preflight: PreflightBehavior.navigation(token()) },
},
expected: NavigationTestResult.SUCCESS,
}), prefix + "success.");
}
// Source: private secure context.
//
// Fetches to the local address space require a successful preflight response
// carrying a PNA-specific header.
subsetTestByKey('from-private', makePreflightTests, {
sourceServer: Server.HTTPS_PRIVATE,
sourceName: 'private',
targetServer: Server.HTTPS_LOCAL,
targetName: 'local',
});
subsetTestByKey("from-private", promise_test_parallel, t => anchorTest(t, {
source: { server: Server.HTTPS_PRIVATE },
target: { server: Server.HTTPS_PRIVATE },
expected: NavigationTestResult.SUCCESS,
}), "private to private: no preflight required.");
subsetTestByKey("from-private", promise_test_parallel, t => anchorTest(t, {
source: { server: Server.HTTPS_PRIVATE },
target: { server: Server.HTTPS_PUBLIC },
expected: NavigationTestResult.SUCCESS,
}), "private to public: no preflight required.");
// Source: public secure context.
//
// Fetches to the local and private address spaces require a successful
// preflight response carrying a PNA-specific header.
subsetTestByKey('from-public', makePreflightTests, {
sourceServer: Server.HTTPS_PUBLIC,
sourceName: "public",
targetServer: Server.HTTPS_LOCAL,
targetName: "local",
});
subsetTestByKey('from-public', makePreflightTests, {
sourceServer: Server.HTTPS_PUBLIC,
sourceName: "public",
targetServer: Server.HTTPS_PRIVATE,
targetName: "private",
});
subsetTestByKey("from-public", promise_test_parallel, t => anchorTest(t, {
source: { server: Server.HTTPS_PUBLIC },
target: { server: Server.HTTPS_PUBLIC },
expected: NavigationTestResult.SUCCESS,
}), "public to public: no preflight required.");
// The following tests verify that `CSP: treat-as-public-address` makes
// documents behave as if they had been served from a public IP address.
subsetTestByKey('from-treat-as-public', makePreflightTests, {
sourceServer: Server.HTTPS_LOCAL,
sourceTreatAsPublic: true,
sourceName: "treat-as-public-address",
targetServer: Server.OTHER_HTTPS_LOCAL,
targetName: "local",
});
subsetTestByKey("from-treat-as-public", promise_test_parallel,
t => anchorTest(t, {
source: {
server: Server.HTTPS_LOCAL,
treatAsPublic: true,
},
target: {server: Server.HTTPS_LOCAL},
expected: NavigationTestResult.SUCCESS,
}),
'treat-as-public-address to local (same-origin): no preflight required.');
subsetTestByKey('from-treat-as-public', makePreflightTests, {
sourceServer: Server.HTTPS_LOCAL,
sourceTreatAsPublic: true,
sourceName: 'treat-as-public-address',
targetServer: Server.HTTPS_PRIVATE,
targetName: 'private',
});
subsetTestByKey("from-treat-as-public", promise_test_parallel,
t => anchorTest(t, {
source: {
server: Server.HTTPS_LOCAL,
treatAsPublic: true,
},
target: {server: Server.HTTPS_PUBLIC},
expected: NavigationTestResult.SUCCESS,
}),
'treat-as-public-address to public: no preflight required.');

Просмотреть файл

@ -0,0 +1,94 @@
// META: script=/common/dispatcher/dispatcher.js
// META: script=/common/utils.js
// META: script=resources/support.sub.js
//
// Spec: https://wicg.github.io/private-network-access/
//
// These tests verify that non-secure contexts cannot open a new window via an
// anchor link to less-public address spaces.
setup(() => {
// Making sure we are in a non secure context, as expected.
assert_false(window.isSecureContext);
});
promise_test_parallel(t => anchorTest(t, {
source: { server: Server.HTTP_LOCAL },
target: { server: Server.HTTP_LOCAL },
expected: NavigationTestResult.SUCCESS,
}), "local to local: no preflight required.");
promise_test_parallel(t => anchorTest(t, {
source: { server: Server.HTTP_LOCAL },
target: { server: Server.HTTP_PRIVATE },
expected: NavigationTestResult.SUCCESS,
}), "local to private: no preflight required.");
promise_test_parallel(t => anchorTest(t, {
source: { server: Server.HTTP_LOCAL },
target: { server: Server.HTTP_PUBLIC },
expected: NavigationTestResult.SUCCESS,
}), "local to public: no preflight required.");
promise_test_parallel(t => anchorTest(t, {
source: { server: Server.HTTP_PRIVATE },
target: { server: Server.HTTP_LOCAL },
expected: NavigationTestResult.FAILURE,
}), "private to local: failure.");
promise_test_parallel(t => anchorTest(t, {
source: { server: Server.HTTP_PRIVATE },
target: { server: Server.HTTP_PRIVATE },
expected: NavigationTestResult.SUCCESS,
}), "private to private: no preflight required.");
promise_test_parallel(t => anchorTest(t, {
source: { server: Server.HTTP_PRIVATE },
target: { server: Server.HTTP_PUBLIC },
expected: NavigationTestResult.SUCCESS,
}), "private to public: no preflight required.");
promise_test_parallel(t => anchorTest(t, {
source: { server: Server.HTTP_PUBLIC },
target: { server: Server.HTTP_LOCAL },
expected: NavigationTestResult.FAILURE,
}), "public to local: failure.");
promise_test_parallel(t => anchorTest(t, {
source: { server: Server.HTTP_PUBLIC },
target: { server: Server.HTTP_PRIVATE },
expected: NavigationTestResult.FAILURE,
}), "public to private: failure.");
promise_test_parallel(t => anchorTest(t, {
source: { server: Server.HTTP_PUBLIC },
target: { server: Server.HTTP_PUBLIC },
expected: NavigationTestResult.SUCCESS,
}), "public to public: no preflight required.");
promise_test_parallel(t => anchorTest(t, {
source: {
server: Server.HTTP_LOCAL,
treatAsPublic: true,
},
target: { server: Server.HTTP_LOCAL },
expected: NavigationTestResult.FAILURE,
}), "treat-as-public-address to local: failure.");
promise_test_parallel(t => anchorTest(t, {
source: {
server: Server.HTTP_LOCAL,
treatAsPublic: true,
},
target: { server: Server.HTTP_PRIVATE },
expected: NavigationTestResult.FAILURE,
}), "treat-as-public-address to private: failure.");
promise_test_parallel(t => anchorTest(t, {
source: {
server: Server.HTTP_LOCAL,
treatAsPublic: true,
},
target: { server: Server.HTTP_PUBLIC },
expected: NavigationTestResult.SUCCESS,
}), "treat-as-public-address to public: no preflight required.");

Просмотреть файл

@ -0,0 +1,16 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Anchor</title>
<body></body>
<script>
window.onmessage = (event) => {
window.onmessage = (event) => parent.postMessage(event.data, "*");
const { url } = event.data;
const anchor = document.createElement('a');
anchor.href = url;
anchor.rel = 'opener';
anchor.target = '_blank';
document.body.appendChild(anchor);
anchor.click();
};
</script>

Просмотреть файл

@ -474,7 +474,7 @@ async function iframeTest(t, { source, target, expected }) {
assert_equals(result, expected);
}
const WindowOpenTestResult = {
const NavigationTestResult = {
SUCCESS: "success",
FAILURE: "timeout",
};
@ -506,6 +506,33 @@ async function windowOpenTest(t, { source, target, expected }) {
assert_equals(result, expected);
}
async function anchorTest(t, { source, target, expected }) {
const targetUrl = preflightUrl(target);
targetUrl.searchParams.set("file", "openee.html");
targetUrl.searchParams.set(
"file-if-no-preflight-received",
"no-preflight-received.html",
);
const sourceUrl =
resolveUrl("resources/anchor.html", sourceResolveOptions(source));
sourceUrl.searchParams.set("url", targetUrl);
const iframe = await appendIframe(t, document, sourceUrl);
const reply = futureMessage({ source: iframe.contentWindow });
iframe.contentWindow.postMessage({ url: targetUrl.href }, "*");
const result = await Promise.race([
reply,
new Promise((resolve) => {
t.step_timeout(() => resolve("timeout"), 4000 /* ms */);
}),
]);
assert_equals(result, expected);
}
// Similar to `iframeTest`, but replaced iframes with fenced frames.
async function fencedFrameTest(t, { source, target, expected }) {
// Allows running tests in parallel.

Просмотреть файл

@ -7,9 +7,9 @@
// META: variant=?include=from-public
// META: variant=?include=from-treat-as-public
//
// These tests verify that secure contexts can navigate iframes to less-public
// address spaces iff the target server responds affirmatively to preflight
// requests.
// These tests verify that secure contexts can navigate to less-public address
// spaces via window.open iff the target server responds affirmatively to
// preflight requests.
setup(() => {
assert_true(window.isSecureContext);
@ -22,26 +22,25 @@ setup(() => {
subsetTestByKey("from-local", promise_test_parallel, t => windowOpenTest(t, {
source: { server: Server.HTTPS_LOCAL },
target: { server: Server.HTTPS_LOCAL },
expected: WindowOpenTestResult.SUCCESS,
expected: NavigationTestResult.SUCCESS,
}), "local to local: no preflight required.");
subsetTestByKey("from-local", promise_test_parallel, t => windowOpenTest(t, {
source: { server: Server.HTTPS_LOCAL },
target: { server: Server.HTTPS_PRIVATE },
expected: WindowOpenTestResult.SUCCESS,
expected: NavigationTestResult.SUCCESS,
}), "local to private: no preflight required.");
subsetTestByKey("from-local", promise_test_parallel, t => windowOpenTest(t, {
source: { server: Server.HTTPS_LOCAL },
target: { server: Server.HTTPS_PUBLIC },
expected: WindowOpenTestResult.SUCCESS,
expected: NavigationTestResult.SUCCESS,
}), "local to public: no preflight required.");
// Generates tests of preflight behavior for a single (source, target) pair.
//
// Scenarios:
//
// - parent navigates child:
// - preflight response has non-2xx HTTP code
// - preflight response is missing CORS headers
// - preflight response is missing the PNA-specific `Access-Control` header
@ -69,7 +68,7 @@ function makePreflightTests({
server: targetServer,
behavior: { preflight: PreflightBehavior.failure() },
},
expected: WindowOpenTestResult.FAILURE,
expected: NavigationTestResult.FAILURE,
}), prefix + "failed preflight.");
promise_test_parallel(t => windowOpenTest(t, {
@ -78,7 +77,7 @@ function makePreflightTests({
server: targetServer,
behavior: { preflight: PreflightBehavior.noCorsHeader(token()) },
},
expected: WindowOpenTestResult.FAILURE,
expected: NavigationTestResult.FAILURE,
}), prefix + "missing CORS headers.");
promise_test_parallel(t => windowOpenTest(t, {
@ -87,7 +86,7 @@ function makePreflightTests({
server: targetServer,
behavior: { preflight: PreflightBehavior.noPnaHeader(token()) },
},
expected: WindowOpenTestResult.FAILURE,
expected: NavigationTestResult.FAILURE,
}), prefix + "missing PNA header.");
promise_test_parallel(t => windowOpenTest(t, {
@ -96,7 +95,7 @@ function makePreflightTests({
server: targetServer,
behavior: { preflight: PreflightBehavior.navigation(token()) },
},
expected: WindowOpenTestResult.SUCCESS,
expected: NavigationTestResult.SUCCESS,
}), prefix + "success.");
}
@ -115,13 +114,13 @@ subsetTestByKey('from-private', makePreflightTests, {
subsetTestByKey("from-private", promise_test_parallel, t => windowOpenTest(t, {
source: { server: Server.HTTPS_PRIVATE },
target: { server: Server.HTTPS_PRIVATE },
expected: WindowOpenTestResult.SUCCESS,
expected: NavigationTestResult.SUCCESS,
}), "private to private: no preflight required.");
subsetTestByKey("from-private", promise_test_parallel, t => windowOpenTest(t, {
source: { server: Server.HTTPS_PRIVATE },
target: { server: Server.HTTPS_PUBLIC },
expected: WindowOpenTestResult.SUCCESS,
expected: NavigationTestResult.SUCCESS,
}), "private to public: no preflight required.");
// Source: public secure context.
@ -146,7 +145,7 @@ subsetTestByKey('from-public', makePreflightTests, {
subsetTestByKey("from-public", promise_test_parallel, t => windowOpenTest(t, {
source: { server: Server.HTTPS_PUBLIC },
target: { server: Server.HTTPS_PUBLIC },
expected: WindowOpenTestResult.SUCCESS,
expected: NavigationTestResult.SUCCESS,
}), "public to public: no preflight required.");
// The following tests verify that `CSP: treat-as-public-address` makes
@ -167,7 +166,7 @@ subsetTestByKey("from-treat-as-public", promise_test_parallel,
treatAsPublic: true,
},
target: {server: Server.HTTPS_LOCAL},
expected: WindowOpenTestResult.SUCCESS,
expected: NavigationTestResult.SUCCESS,
}),
'treat-as-public-address to local (same-origin): no preflight required.');
@ -186,7 +185,7 @@ subsetTestByKey("from-treat-as-public", promise_test_parallel,
treatAsPublic: true,
},
target: {server: Server.HTTPS_PUBLIC},
expected: WindowOpenTestResult.SUCCESS,
expected: NavigationTestResult.SUCCESS,
}),
'treat-as-public-address to public: no preflight required.');
@ -200,6 +199,6 @@ promise_test_parallel(
server: Server.HTTPS_PUBLIC,
behavior: {preflight: PreflightBehavior.optionalSuccess(token())}
},
expected: WindowOpenTestResult.SUCCESS,
expected: NavigationTestResult.SUCCESS,
}),
'treat-as-public-address to local: optional preflight');

Просмотреть файл

@ -15,55 +15,55 @@ setup(() => {
promise_test_parallel(t => windowOpenTest(t, {
source: { server: Server.HTTP_LOCAL },
target: { server: Server.HTTP_LOCAL },
expected: WindowOpenTestResult.SUCCESS,
expected: NavigationTestResult.SUCCESS,
}), "local to local: no preflight required.");
promise_test_parallel(t => windowOpenTest(t, {
source: { server: Server.HTTP_LOCAL },
target: { server: Server.HTTP_PRIVATE },
expected: WindowOpenTestResult.SUCCESS,
expected: NavigationTestResult.SUCCESS,
}), "local to private: no preflight required.");
promise_test_parallel(t => windowOpenTest(t, {
source: { server: Server.HTTP_LOCAL },
target: { server: Server.HTTP_PUBLIC },
expected: WindowOpenTestResult.SUCCESS,
expected: NavigationTestResult.SUCCESS,
}), "local to public: no preflight required.");
promise_test_parallel(t => windowOpenTest(t, {
source: { server: Server.HTTP_PRIVATE },
target: { server: Server.HTTP_LOCAL },
expected: WindowOpenTestResult.FAILURE,
expected: NavigationTestResult.FAILURE,
}), "private to local: failure.");
promise_test_parallel(t => windowOpenTest(t, {
source: { server: Server.HTTP_PRIVATE },
target: { server: Server.HTTP_PRIVATE },
expected: WindowOpenTestResult.SUCCESS,
expected: NavigationTestResult.SUCCESS,
}), "private to private: no preflight required.");
promise_test_parallel(t => windowOpenTest(t, {
source: { server: Server.HTTP_PRIVATE },
target: { server: Server.HTTP_PUBLIC },
expected: WindowOpenTestResult.SUCCESS,
expected: NavigationTestResult.SUCCESS,
}), "private to public: no preflight required.");
promise_test_parallel(t => windowOpenTest(t, {
source: { server: Server.HTTP_PUBLIC },
target: { server: Server.HTTP_LOCAL },
expected: WindowOpenTestResult.FAILURE,
expected: NavigationTestResult.FAILURE,
}), "public to local: failure.");
promise_test_parallel(t => windowOpenTest(t, {
source: { server: Server.HTTP_PUBLIC },
target: { server: Server.HTTP_PRIVATE },
expected: WindowOpenTestResult.FAILURE,
expected: NavigationTestResult.FAILURE,
}), "public to private: failure.");
promise_test_parallel(t => windowOpenTest(t, {
source: { server: Server.HTTP_PUBLIC },
target: { server: Server.HTTP_PUBLIC },
expected: WindowOpenTestResult.SUCCESS,
expected: NavigationTestResult.SUCCESS,
}), "public to public: no preflight required.");
promise_test_parallel(t => windowOpenTest(t, {
@ -72,7 +72,7 @@ promise_test_parallel(t => windowOpenTest(t, {
treatAsPublic: true,
},
target: { server: Server.HTTP_LOCAL },
expected: WindowOpenTestResult.FAILURE,
expected: NavigationTestResult.FAILURE,
}), "treat-as-public-address to local: failure.");
promise_test_parallel(t => windowOpenTest(t, {
@ -81,7 +81,7 @@ promise_test_parallel(t => windowOpenTest(t, {
treatAsPublic: true,
},
target: { server: Server.HTTP_PRIVATE },
expected: WindowOpenTestResult.FAILURE,
expected: NavigationTestResult.FAILURE,
}), "treat-as-public-address to private: failure.");
promise_test_parallel(t => windowOpenTest(t, {
@ -90,5 +90,5 @@ promise_test_parallel(t => windowOpenTest(t, {
treatAsPublic: true,
},
target: { server: Server.HTTP_PUBLIC },
expected: WindowOpenTestResult.SUCCESS,
expected: NavigationTestResult.SUCCESS,
}), "treat-as-public-address to public: no preflight required.");