Relax same-site prefetch referrer policy check
Applying the sufficiently-strict referrer policy restriction to all
prefetches was found to break legitimate same-site use cases. We now
only enforce this for cross-site prefetches. This also makes the logic
consistent between prefetch and prerender.
Bug: 1379846, 1355146
Change-Id: I945cc4f584af83e42cf80f146ee96823f2ada27a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4077268
Auto-Submit: Kevin McNee <mcnee@chromium.org>
Reviewed-by: Jeremy Roman <jbroman@chromium.org>
Commit-Queue: Jeremy Roman <jbroman@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1079453}
diff --git a/speculation-rules/prefetch/referrer-policy-from-rules.https.html b/speculation-rules/prefetch/referrer-policy-from-rules.https.html
index ce3db0f..4120bf6 100644
--- a/speculation-rules/prefetch/referrer-policy-from-rules.https.html
+++ b/speculation-rules/prefetch/referrer-policy-from-rules.https.html
@@ -60,19 +60,18 @@
const agent = await spawnWindow(t);
await agent.setReferrerPolicy("unsafe-url");
- const nextURL = agent.getExecutorURL({ page: 2 });
- await agent.forceSinglePrefetch(nextURL, { referrer_policy: "no-referrer" });
+ const nextURL = agent.getExecutorURL({ hostname: PREFETCH_PROXY_BYPASS_HOST, page: 2 });
+ await agent.forceSinglePrefetch(
+ nextURL, { referrer_policy: "no-referrer", requires: ["anonymous-client-ip-when-cross-origin"] });
await agent.navigate(nextURL);
// This referring page's referrer policy would not be eligible for
- // prefetching, but setting a sufficiently strict policy in the rule allows
- // for prefetching.
- // TODO(crbug.com/1379846): This test will be trivialized once the prefetch
- // referrer policy requirements are relaxed for same-site.
+ // cross-site prefetching, but setting a sufficiently strict policy in the
+ // rule allows for prefetching.
const headers = await agent.getRequestHeaders();
assert_prefetched(headers, "must be prefetched");
assert_equals(headers.referer, '', "must send no referrer");
-}, 'with "no-referrer" referrer policy in rule set overriding "unsafe-url" of referring page');
+}, 'with "no-referrer" referrer policy in rule set overriding "unsafe-url" of cross-site referring page');
subsetTest(promise_test, async t => {
assert_implements(HTMLScriptElement.supports('speculationrules'), "Speculation Rules not supported");
@@ -109,17 +108,17 @@
await agent.setReferrerPolicy("strict-origin");
const expectedReferrer = agent.getExecutorURL().origin + "/";
- const nextURL = agent.getExecutorURL({ page: 2 });
- await agent.forceSinglePrefetch(nextURL, { referrer_policy: "unsafe-url" });
+ const nextURL = agent.getExecutorURL({ hostname: PREFETCH_PROXY_BYPASS_HOST, page: 2 });
+ await agent.forceSinglePrefetch(
+ nextURL, { referrer_policy: "unsafe-url", requires: ["anonymous-client-ip-when-cross-origin"] });
await agent.navigate(nextURL);
// This referring page's referrer policy would normally make it eligible for
- // prefetching, but setting an unacceptable policy in the rule makes it ineligible.
- // TODO(crbug.com/1379846): This test will be invalidated once the prefetch
- // referrer policy requirements are relaxed for same-site.
+ // cross-site prefetching, but setting an unacceptable policy in the rule
+ // makes it ineligible.
const headers = await agent.getRequestHeaders();
assert_not_prefetched(headers, "must not be prefetched");
assert_equals(headers.referer, expectedReferrer, "must send the origin as the referrer");
-}, 'with "unsafe-url" referrer policy in rule set overriding "strict-origin" of referring page');
+}, 'with "unsafe-url" referrer policy in rule set overriding "strict-origin" of cross-site referring page');
</script>
diff --git a/speculation-rules/prefetch/referrer-policy-not-accepted.https.html b/speculation-rules/prefetch/referrer-policy-not-accepted.https.html
index 25b1128..d7c003b 100644
--- a/speculation-rules/prefetch/referrer-policy-not-accepted.https.html
+++ b/speculation-rules/prefetch/referrer-policy-not-accepted.https.html
@@ -1,15 +1,21 @@
<!DOCTYPE html>
<title>Prefetch attempts with an unacceptable referrer policy</title>
+
+<!--Split test cases due to the use of timeouts in speculation rules test utilities.-->
+<meta name="variant" content="?1-1">
+<meta name="variant" content="?2-last">
+
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/common/subset-tests.js"></script>
<script src="/common/utils.js"></script>
<script src="resources/utils.sub.js"></script>
<script>
"use strict";
-promise_test(async t => {
+subsetTest(promise_test, async t => {
assert_implements(HTMLScriptElement.supports('speculationrules'), "Speculation Rules not supported");
const agent = await spawnWindow(t);
@@ -17,13 +23,31 @@
const expectedReferrer = agent.getExecutorURL().href;
const nextURL = agent.getExecutorURL({ page: 2 });
- // This prefetch attempt should be ignored.
await agent.forceSinglePrefetch(nextURL);
await agent.navigate(nextURL);
const headers = await agent.getRequestHeaders();
+ // The referrer policy restriction does not apply to same-site prefetch.
+ assert_prefetched(headers, "must be prefetched");
+ assert_equals(headers.referer, expectedReferrer, "must send the full URL as the referrer");
+}, 'with "unsafe-url" referrer policy on same-site referring page');
+
+subsetTest(promise_test, async t => {
+ assert_implements(HTMLScriptElement.supports('speculationrules'), "Speculation Rules not supported");
+
+ const agent = await spawnWindow(t);
+ await agent.setReferrerPolicy("unsafe-url");
+ const expectedReferrer = agent.getExecutorURL().href;
+
+ const nextURL = agent.getExecutorURL({ hostname: PREFETCH_PROXY_BYPASS_HOST, page: 2 });
+ // This prefetch attempt should be ignored.
+ await agent.forceSinglePrefetch(
+ nextURL, { requires: ["anonymous-client-ip-when-cross-origin"] });
+ await agent.navigate(nextURL);
+
+ const headers = await agent.getRequestHeaders();
assert_not_prefetched(headers, "must not be prefetched");
assert_equals(headers.referer, expectedReferrer, "must send the full URL as the referrer");
-}, 'with "unsafe-url" referrer policy');
+}, 'with "unsafe-url" referrer policy on cross-site referring page');
</script>
diff --git a/speculation-rules/prefetch/resources/utils.sub.js b/speculation-rules/prefetch/resources/utils.sub.js
index b29dd6b..a306b8c 100644
--- a/speculation-rules/prefetch/resources/utils.sub.js
+++ b/speculation-rules/prefetch/resources/utils.sub.js
@@ -159,7 +159,8 @@
function assert_prefetched (requestHeaders, description) {
assert_in_array(requestHeaders.purpose, ["", "prefetch"], "The vendor-specific header Purpose, if present, must be 'prefetch'.");
- assert_equals(requestHeaders.sec_purpose, "prefetch", description);
+ assert_in_array(requestHeaders.sec_purpose,
+ ["prefetch", "prefetch;anonymous-client-ip"], description);
}
function assert_not_prefetched (requestHeaders, description){