summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/referrer-policy/generic
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/referrer-policy/generic
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/referrer-policy/generic')
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/first-meta-changed-after-second-added.http.html36
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/iframe-src-change.html37
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html26
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html.headers1
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/iframe-upgrade-request-to-same-origin.sub.https.html21
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/iframe-upgrade-request-to-same-origin.sub.https.html.headers2
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-about-blank.html107
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-data.html27
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-document-write.html34
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-history-about-blank.html80
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-history-about-srcdoc.html73
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-javascript-child.html77
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-javascript.html45
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-srcdoc-child.html34
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-srcdoc.html45
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/inheritance/popup-inheritance-about-blank.html105
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/inheritance/popup-inheritance-form-submission.html30
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/inheritance/resources/make-html-script.js19
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/inheritance/resources/submit-form-and-remove-frame.html10
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/inheritance/workers.html47
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/link-rel-prefetch.html28
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/meta-referrer-outofhead-fetch.http.html21
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/meta-referrer-removed-1.http.html25
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/meta-referrer-removed-2.http.html34
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/meta-tag-in-svg-image.html31
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/multiple-headers-and-values.html30
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/multiple-headers-and-values.html.headers2
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/multiple-headers-combined.html30
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/multiple-headers-combined.html.headers1
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/multiple-headers-one-invalid.html34
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/multiple-headers-one-invalid.html.headers2
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/multiple-headers-one-unknown-token.html30
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/multiple-headers-one-unknown-token.html.headers2
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/multiple-headers.html30
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/multiple-headers.html.headers2
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/resources/img-with-referrer-policy.svg6
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/resources/referrer.py10
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/sandboxed-iframe-with-opaque-origin.html93
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/sanity-checker.js46
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/second-meta-referrer-added-before-first.http.html31
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/subresource-test/area-navigate.html39
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/subresource-test/attr-referrer-invalid-value.html25
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/subresource-test/fetch-messaging.html42
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/subresource-test/iframe-messaging.html38
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/subresource-test/image-decoding.html38
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/subresource-test/link-navigate.html38
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/subresource-test/script-messaging.html38
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/subresource-test/worker-messaging.html38
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/subresource-test/xhr-messaging.html38
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/test-case.sub.js127
-rw-r--r--testing/web-platform/tests/referrer-policy/generic/unsupported-csp-referrer-directive.html29
51 files changed, 1834 insertions, 0 deletions
diff --git a/testing/web-platform/tests/referrer-policy/generic/first-meta-changed-after-second-added.http.html b/testing/web-platform/tests/referrer-policy/generic/first-meta-changed-after-second-added.http.html
new file mode 100644
index 0000000000..2ee5ade8c0
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/first-meta-changed-after-second-added.http.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+
+ <meta name="referrer" content="no-referrer" id="referrermeta">
+</head>
+<body>
+ <script>
+ async function fetchAndGetReferrer() {
+ let response = await fetch('/common/security-features/subresource/xhr.py');
+ let data = await response.json();
+ return data.headers.referer;
+ }
+
+ promise_test(async t => {
+ assert_equals(await fetchAndGetReferrer(), undefined,
+ 'referrer should not be set');
+
+ // Add second meta _before_ first meta.
+ const first_meta = document.getElementById('referrermeta');
+ const second_meta = document.createElement('meta');
+ second_meta.name = 'referrer';
+ second_meta.content = 'strict-origin';
+ document.head.appendChild(second_meta);
+ assert_equals(await fetchAndGetReferrer(), window.location.origin + '/',
+ 'referrer should be origin only');
+
+ // Update content attribute of first meta.
+ first_meta.content = 'unsafe-url';
+ assert_equals(await fetchAndGetReferrer(), window.location.href,
+ 'referrer should be full url');
+ }, 'document referrer policy is the value of the most recently modified <meta name="referrer"');
+
+ </script>
+</body>
diff --git a/testing/web-platform/tests/referrer-policy/generic/iframe-src-change.html b/testing/web-platform/tests/referrer-policy/generic/iframe-src-change.html
new file mode 100644
index 0000000000..15202a76a1
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/iframe-src-change.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<script>
+function nextMessage() {
+ return new Promise((resolve, reject) => {
+ window.addEventListener('message', e => resolve(e.data), {once: true});
+ });
+}
+
+promise_test(async () => {
+ let iframe = document.createElement('iframe');
+ iframe.setAttribute('src', '/common/security-features/subresource/document.py?first')
+ iframe.setAttribute('referrerpolicy', 'no-referrer');
+ document.body.appendChild(iframe);
+
+ try {
+ {
+ let {referrer: documentReferrer, headers: {referer: httpReferrer}} = await nextMessage();
+ assert_equals(httpReferrer, undefined, 'expected no HTTP Referer header on initial load');
+ assert_equals(documentReferrer, undefined, 'expected no document.referrer on initial load');
+ }
+
+ iframe.setAttribute('src', '/common/security-features/subresource/document.py?second');
+
+ {
+ let {referrer: documentReferrer, headers: {referer: httpReferrer}} = await nextMessage();
+ assert_equals(httpReferrer, undefined, 'expected no HTTP Referer header on src change');
+ assert_equals(documentReferrer, undefined, 'expected no document.referrer on src change');
+ }
+ } finally {
+ iframe.remove();
+ }
+}, "Checks that referrerpolicy is respected when an iframe's src changes.");
+</script>
+</body>
diff --git a/testing/web-platform/tests/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html b/testing/web-platform/tests/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html
new file mode 100644
index 0000000000..4040072ab9
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<link rel="author" title="Dominic Farolino" href="dom@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<!-- We need to set the CSP via the <meta> tag. If we were to use the HTTP
+ header, we'd have to specify the absolute HTTPS URL of the test harness and
+ reporter, but then this file is not recognized as a test harness test, and
+ will not run -->
+<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
+<body>
+<iframe id="iframe"></iframe>
+<script>
+async_test(t => {
+ const iframe = document.querySelector('iframe');
+ iframe.src =
+ 'http://{{domains[www]}}:{{ports[https][0]}}/referrer-policy/generic/resources/referrer.py';
+
+ addEventListener('message', t.step_func_done(msg => {
+ const referrer = msg.data;
+ assert_equals(referrer, new URL(location.href).origin + '/',
+ "The referrer header sent for the iframe request should be redacted");
+ }));
+}, "If an insecure iframe request is upgraded to https to be cross-origin, " +
+ "referrer policies that consider same-origin-ness should be applied correctly");
+</script>
+</body>
diff --git a/testing/web-platform/tests/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html.headers b/testing/web-platform/tests/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html.headers
new file mode 100644
index 0000000000..ad768e6329
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/iframe-upgrade-request-to-cross-origin.sub.html.headers
@@ -0,0 +1 @@
+Referrer-Policy: origin-when-cross-origin
diff --git a/testing/web-platform/tests/referrer-policy/generic/iframe-upgrade-request-to-same-origin.sub.https.html b/testing/web-platform/tests/referrer-policy/generic/iframe-upgrade-request-to-same-origin.sub.https.html
new file mode 100644
index 0000000000..f9163bec54
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/iframe-upgrade-request-to-same-origin.sub.https.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<link rel="author" title="Dominic Farolino" href="dom@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<iframe id="iframe"></iframe>
+<script>
+async_test(t => {
+ const iframe = document.querySelector('iframe');
+ const insecure_origin = new URL(location.href).origin.replace("https", "http");
+ iframe.src = insecure_origin + '/referrer-policy/generic/resources/referrer.py';
+
+ addEventListener('message', t.step_func_done(msg => {
+ const referrer = msg.data;
+ assert_equals(referrer, location.href,
+ "The referrer header sent for the iframe request should not be redacted");
+ }));
+}, "If an insecure iframe request is upgraded to https to be same-origin, " +
+ "referrer policies that consider same-origin-ness should be applied correctly");
+</script>
+</body>
diff --git a/testing/web-platform/tests/referrer-policy/generic/iframe-upgrade-request-to-same-origin.sub.https.html.headers b/testing/web-platform/tests/referrer-policy/generic/iframe-upgrade-request-to-same-origin.sub.https.html.headers
new file mode 100644
index 0000000000..fd9ee0f032
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/iframe-upgrade-request-to-same-origin.sub.https.html.headers
@@ -0,0 +1,2 @@
+Content-Security-Policy: upgrade-insecure-requests
+Referrer-Policy: origin-when-cross-origin
diff --git a/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-about-blank.html b/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-about-blank.html
new file mode 100644
index 0000000000..fc7d39a4cf
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-about-blank.html
@@ -0,0 +1,107 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Referrer Policy: iframe src="about:blank"</title>
+<link rel="author" title="Hiroshige Hayashizaki" href="mailto:hiroshige@chromium.org">
+<link rel="author" title="Dom Farolino" href="mailto:dom@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name="referrer" content="origin">
+<body>
+<script>
+const testFetchClientReferrer =
+ async_test("The fetch() API in an about:blank iframe with the 'client' " +
+ "referrer is fetched with no 'Referer' header");
+const testFetchURLReferrer =
+ async_test("The fetch() API in an about:blank iframe with a custom URL " +
+ "referrer is fetched with a 'Referer` header that uses the " +
+ "outer document's URL along with its referrer policy");
+const testDocumentReferrer =
+ async_test("The value of document.referrer in an about:blank iframe is the " +
+ "outer document's full URL, regardless of referrer policy");
+const testSubresource =
+ async_test("A subresource fetched from an about:blank iframe is fetched " +
+ "with no 'Referer' header");
+
+window.addEventListener("message", msg => {
+ const test_name = msg.data.test;
+ const referrer = msg.data.referrer;
+ if (test_name === "testFetchClientReferrer") {
+ testFetchClientReferrer.step_func_done(() => {
+ // Because the URL of the Document of <iframe src="about:blank"> is
+ // "about:blank", the stripped URL is no referrer:
+ // https://w3c.github.io/webappsec-referrer-policy/#strip-url.
+ assert_equals(referrer, undefined);
+ })();
+ } else if (test_name === "testFetchURLReferrer") {
+ // <iframe src="about:blank"> inherits its parent's referrer policy.
+ // Note: Setting an explicit URL as referrer succeeds
+ // because the same-origin check at
+ // https://fetch.spec.whatwg.org/#dom-request
+ // is done against <iframe>'s origin, which inherits the parent
+ // Document's origin == location.orgin. Furthermore, since the iframe
+ // inherits its parent's referrer policy, the URL should be restricted to
+ // its origin.
+ testFetchURLReferrer.step_func_done(() => {
+ assert_equals(referrer, location.origin + '/');
+ })();
+ } else if (test_name === "testDocumentReferrer") {
+ // The referrer of the initial document in an about:blank iframe is set to
+ // its creating document's URL, unredacted by a referrer policy, as per step
+ // 13 of:
+ // https://html.spec.whatwg.org/multipage/browsers.html#creating-a-new-browsing-context.
+ testDocumentReferrer.step_func_done(() => {
+ assert_equals(referrer, location.href);
+ })();
+ } else if (test_name === "testSubresource") {
+ // Because the URL of the Document of <iframe src="about:blank"> is
+ // "about:blank", the stripped URL is no referrer:
+ // https://w3c.github.io/webappsec-referrer-policy/#strip-url.
+ testSubresource.step_func_done(() => {
+ assert_equals(referrer, "");
+ })();
+ }
+});
+
+const iframe = document.createElement("iframe");
+
+iframe.addEventListener("load", function() {
+ const iframe_script = iframe.contentDocument.createElement('script');
+ iframe_script.textContent = `
+ // Test fetch() API with default "client" referrer.
+ fetch("${location.origin}/common/security-features/subresource/xhr.py?name=testFetchClientReferrer")
+ .then(r => r.json())
+ .then(j => {
+ top.postMessage({test: "testFetchClientReferrer", referrer: j.headers.referer}, "*")
+ }).catch(e => {
+ top.postMessage({test: "testFetchClientReferrer", referrer: "FAILURE"}, "*");
+ });
+
+ // Test fetch() API with custom URL referrer.
+ fetch("${location.origin}/common/security-features/subresource/xhr.py?name=URL",
+ {referrer: "${location.href}/custom"})
+ .then(r => r.json())
+ .then(j => {
+ top.postMessage({test: "testFetchURLReferrer", referrer: j.headers.referer}, "*")
+ }).catch(e => {
+ top.postMessage({test: "testFetchURLReferrer", referrer: "FAILURE"}, "*");
+ });
+
+ // Test document.referrer.
+ top.postMessage({test: "testDocumentReferrer", referrer: document.referrer}, "*");
+
+ // Test a subresource being fetched by the iframe.
+ const subresource_script = document.createElement('script');
+ subresource_script.src = "${location.origin}/common/security-features/subresource/referrer.py";
+ subresource_script.onload = e => {
+ top.postMessage({test: "testSubresource", referrer: window.referrer}, "*");
+ }
+ subresource_script.onerror = function(e) {
+ top.postMessage({test: "testSubresource", referrer: "FAILURE"}, "*");
+ };
+ document.head.appendChild(subresource_script);
+ `;
+ iframe.contentDocument.body.appendChild(iframe_script);
+});
+
+document.body.appendChild(iframe);
+</script>
diff --git a/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-data.html b/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-data.html
new file mode 100644
index 0000000000..1d39781e30
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-data.html
@@ -0,0 +1,27 @@
+<html>
+ <head>
+ <title>Referrer Policy: iframes with data url uses no referrer</title>
+ <link rel="help" href="https://www.w3.org/TR/referrer-policy/#referrer-policy-delivery-nested">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="resources/make-html-script.js"></script>
+ <meta name="referrer" content="origin">
+ </head>
+ <body onload="runTest()">
+ <h1>Referrer Policy: iframes with data url uses no referrer</h1>
+ <script>
+ let test = async_test("iframes with data url uses no referrer");
+ window.addEventListener("message", test.step_func_done(msg => {
+ assert_equals(msg.data.referrer, undefined);
+ }));
+
+ function runTest() {
+ let iframe = document.createElement("iframe");
+ iframe.src = `data:text/html,${createScriptString(get_host_info().REMOTE_ORIGIN)}`;
+ document.body.appendChild(iframe);
+ }
+ </script>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-document-write.html b/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-document-write.html
new file mode 100644
index 0000000000..c88586aaf6
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-document-write.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<title>Referrer Policy: iframes with document.write()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="resources/make-html-script.js"></script>
+<meta name="referrer" content="origin">
+<div id="log"></div>
+<script>
+ let reportedReferrer = () => {
+ return new Promise(resolve => {
+ window.addEventListener("message", msg => resolve(msg.data.referrer));
+ });
+ };
+
+ const iframe = document.createElement("iframe");
+ promise_test(async t => {
+ let referrer_of_srcdoc_iframe = reportedReferrer();
+ const script_to_fetch_cross_origin_resource =
+ createScriptString(get_host_info().REMOTE_ORIGIN, location.origin + "/custom");
+ iframe.srcdoc = `<head><meta name="referrer" content="unsafe-url"></head>`
+ + script_to_fetch_cross_origin_resource;
+ document.body.appendChild(iframe);
+ assert_equals(await referrer_of_srcdoc_iframe, self.origin + "/custom",
+ "Srcdoc iframe setting referrer policy via meta header should use that referrer policy.");
+
+ let referrer_after_document_open = reportedReferrer();
+ iframe.contentDocument.open();
+ iframe.contentDocument.write(script_to_fetch_cross_origin_resource);
+ iframe.contentDocument.close();
+ assert_equals(await referrer_after_document_open, self.origin + "/custom",
+ "Referrer policy should not change after document.open().");
+ }, "document.open() should not change the referrer policy of the opened document.");
+</script>
diff --git a/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-history-about-blank.html b/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-history-about-blank.html
new file mode 100644
index 0000000000..8d68ffb5ff
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-history-about-blank.html
@@ -0,0 +1,80 @@
+<!doctype html>
+<title>Referrer Policy: navigating back to an about:blank iframe reuses the original referrer policy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name="referrer" content="no-referrer">
+<div id="log"></div>
+<script>
+ let checkReferrer = document => {
+ let script = document.createElement('script');
+ script.innerText = `
+ fetch("${origin}/common/security-features/subresource/xhr.py",
+ {referrer: "${location.origin}/custom"})
+ .then(r => r.json())
+ .then(j => {
+ top.postMessage({referrer: j.headers.referer}, "*")
+ }).catch(e => {
+ top.postMessage({referrer: "FAILURE"}, "*");
+ });
+ `
+
+ let referrer = new Promise(resolve => {
+ window.addEventListener("message", function listener(msg) {
+ window.removeEventListener("message", listener, false);
+ resolve(msg.data.referrer);
+ });
+ });
+
+ document.body.appendChild(script);
+
+ return referrer;
+ };
+
+ let iframeLoaded = iframe => {
+ return new Promise(resolve => {
+ iframe.onload = resolve;
+ });
+ };
+
+ promise_test(async t => {
+ // 1. Create an iframe and navigate it to about:blank.
+ // (We cannot just create an empty iframe since the initial empty
+ // document will get its history entry replaced, so we cannot
+ // navigate back to it.)
+ const iframe = document.createElement("iframe");
+ iframe.name = 'test_frame';
+ iframe.src = "/referrer-policy";
+ document.body.appendChild(iframe);
+ await iframeLoaded(iframe);
+
+ window.open('about:blank', 'test_frame');
+ await iframeLoaded(iframe);
+ let referrer_1 = await checkReferrer(iframe.contentDocument);
+ assert_equals(referrer_1, undefined,
+ "First navigation uses correct policy.");
+
+ // 2. Change the referrer policy of the iframe.
+ let meta = iframe.contentDocument.createElement('meta');
+ meta.name = 'referrer';
+ meta.content = "unsafe-url";
+ iframe.contentDocument.head.appendChild(meta);
+
+ let referrer_2 = await checkReferrer(iframe.contentDocument);
+ assert_equals(referrer_2, location.origin + '/custom',
+ "Referrer policy correctly changed.");
+
+ // 3. Navigate the iframe elsewhere.
+ window.open('/referrer-policy', 'test_frame');
+ await iframeLoaded(iframe);
+
+ // 4. Navigate the iframe back.
+ iframe.contentWindow.history.back();
+ await iframeLoaded(iframe);
+
+ let referrer_3 = await checkReferrer(iframe.contentDocument);
+ assert_equals(referrer_3, undefined,
+ "History navigation reuses original policy.");
+ document.body.removeChild(iframe);
+ }, "History navigation reuses original policy.");
+
+</script>
diff --git a/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-history-about-srcdoc.html b/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-history-about-srcdoc.html
new file mode 100644
index 0000000000..91ac5fc139
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-history-about-srcdoc.html
@@ -0,0 +1,73 @@
+<!doctype html>
+<title>Referrer Policy: navigating back to an about:srcdoc iframe reuses the original referrer policy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="resources/make-html-script.js"></script>
+<meta name="referrer" content="no-referrer">
+<div id="log"></div>
+<script>
+ let reportedReferrer = () => {
+ return new Promise(resolve => {
+ window.addEventListener("message", function listener(msg) {
+ window.removeEventListener("message", listener, false);
+ resolve(msg.data.referrer);
+ });
+ });
+ };
+
+ let iframeLoaded = iframe => {
+ return new Promise(resolve => {
+ iframe.onload = resolve;
+ });
+ };
+
+ promise_test(async t => {
+ // 1. Create an about:srcdoc iframe.
+ const iframe = document.createElement("iframe");
+ iframe.name = 'test_frame';
+ let iframe_load_1 = iframeLoaded(iframe);
+ let referrer_1 = reportedReferrer();
+ iframe.srcdoc = createScriptString(get_host_info().REMOTE_ORIGIN,
+ location.origin + "/custom");
+ document.body.appendChild(iframe);
+ await iframe_load_1;
+ let referrer_1_result = await referrer_1;
+
+ // 2. Change the referrer policy of the main document.
+ document.getElementsByTagName('meta')[0].content = "unsafe-url";
+
+ // 3. Navigate the iframe elsewhere.
+ let iframe_load_2 = iframeLoaded(iframe);
+ window.open('/referrer-policy', 'test_frame');
+ await iframe_load_2;
+
+ // 4. Navigate the iframe back.
+ let iframe_load_3 = iframeLoaded(iframe);
+ let referrer_2 = reportedReferrer();
+ iframe.contentWindow.history.back();
+ await iframe_load_3;
+
+ // Despite the main document has changed its referrer policy in (2), the
+ // reported referrer for the history navigation to about:srcdoc in (4) must
+ // match with the one originally reported in (1).
+ assert_equals(referrer_1_result, undefined,
+ "First navigation uses correct policy.");
+ assert_equals(await referrer_2, undefined,
+ "History navigation reuses original policy.");
+ }, "History navigation reuses original policy.");
+
+ promise_test(async t => {
+ // If we initiate a new about:srcdoc navigation, the new referrer policy
+ // should apply.
+ const new_iframe = document.createElement("iframe");
+ let new_iframe_load = iframeLoaded(new_iframe);
+ let new_iframe_referrer = reportedReferrer();
+ new_iframe.srcdoc = createScriptString(get_host_info().REMOTE_ORIGIN,
+ location.origin + "/custom");
+ document.body.appendChild(new_iframe);
+ await new_iframe_load;
+
+ assert_equals(await new_iframe_referrer, self.origin + '/custom');
+ }, "New srcdoc iframe uses new policy.");
+</script>
diff --git a/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-javascript-child.html b/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-javascript-child.html
new file mode 100644
index 0000000000..491f104de4
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-javascript-child.html
@@ -0,0 +1,77 @@
+<!doctype html>
+<title>Referrer Policy: iframes with javascript url reuse referrer policy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="resources/make-html-script.js"></script>
+<meta name="referrer" content="unsafe-url">
+<div id="log"></div>
+<script>
+[
+ {
+ srcDocPolicy: ``,
+ expected: location.origin + "/custom"
+ },
+ {
+ srcDocPolicy: `<meta name="referrer" content="no-referrer">`,
+ expected: undefined
+ }
+].forEach(({ srcDocPolicy, expected }) => {
+ promise_test(t => {
+ return new Promise(resolve => {
+ window.addEventListener("message", t.step_func(msg => {
+ assert_equals(msg.data.referrer, expected);
+ resolve();
+ }), { once:true });
+
+ const iframe = document.createElement("iframe");
+ t.add_cleanup(() => iframe.remove());
+ iframe.srcdoc = `${srcDocPolicy}<body><h1>Outer iframe</h1></body>`;
+ iframe.onload = t.step_func(() => {
+ iframe.onload = null;
+ const iframeChild = iframe.contentDocument.createElement("iframe");
+ // We add a custom referrer to the fetch request. Otherwise,
+ // since the frame's URL is "about:blank", the Referer header will
+ // always be empty:
+ // https://w3c.github.io/webappsec-referrer-policy/#strip-url.
+ iframeChild.src = `javascript:'${createScriptString(get_host_info().REMOTE_ORIGIN, location.origin+"/custom")}'`;
+ iframe.contentDocument.body.appendChild(iframeChild);
+ });
+ document.body.appendChild(iframe);
+ });
+ });
+});
+
+[
+ {
+ srcDocPolicy: ``,
+ expected: location.href // Executing javascript does not change the document url.
+ // Since the algorithm for computing the referrer in a srcdoc
+ // iframe defers recursively to the parent, the expected
+ // referrer should be the full url of the main document.
+ },
+ {
+ srcDocPolicy: `<meta name="referrer" content="no-referrer">`,
+ expected: undefined
+ }
+].forEach(({ srcDocPolicy, expected }) => {
+ promise_test(t => {
+ return new Promise(resolve => {
+ window.addEventListener("message", t.step_func(msg => {
+ assert_equals(msg.data.referrer, expected);
+ resolve();
+ }), { once:true });
+
+ const iframe = document.createElement("iframe");
+ t.add_cleanup(() => iframe.remove());
+ iframe.srcdoc = `${srcDocPolicy}<body><h1>Outer iframe</h1></body>`;
+ iframe.onload = t.step_func(() => {
+ iframe.onload = null;
+ iframe.contentWindow.location = `javascript:'${createScriptString(get_host_info().REMOTE_ORIGIN)}'`;
+ });
+ document.body.appendChild(iframe);
+ });
+ });
+});
+
+</script>
diff --git a/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-javascript.html b/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-javascript.html
new file mode 100644
index 0000000000..cf1f099c63
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-javascript.html
@@ -0,0 +1,45 @@
+<!doctype html>
+<title>Referrer Policy: iframes with javascript url reuse referrer policy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="resources/make-html-script.js"></script>
+<meta name="referrer" content="unsafe-url">
+<div id="log"></div>
+<script>
+
+[
+ {
+ fetchReferrer: "",
+ // Because the URL of the Document of <iframe src="javascript:..."> is
+ // "about:blank", the stripped URL is no referrer:
+ // https://w3c.github.io/webappsec-referrer-policy/#strip-url.
+ expected: undefined
+ },
+ {
+ fetchReferrer: location.origin+"/custom",
+ // <iframe src="javascript:..."> inherits its parent's referrer policy.
+ // Note: Setting an explicit URL as referrer succeeds
+ // because the same-origin check at
+ // https://fetch.spec.whatwg.org/#dom-request
+ // is done against <iframe>'s origin, which inherits the parent
+ // Document's origin == location.orgin. Furthermore, since the iframe
+ // inherits its parent's referrer policy, the URL should be restricted to
+ // its origin.
+ expected: self.origin + "/custom"
+ }
+].forEach(({ fetchReferrer, expected }) => {
+ promise_test(t => {
+ return new Promise(resolve => {
+ window.addEventListener("message", t.step_func(msg => {
+ assert_equals(msg.data.referrer, expected);
+ resolve();
+ }), { once: true });
+ const iframe = document.createElement("iframe");
+ iframe.src = `javascript:'${createScriptString(get_host_info().REMOTE_ORIGIN, fetchReferrer)}'`;
+ document.body.appendChild(iframe);
+ });
+ });
+});
+
+</script>
diff --git a/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-srcdoc-child.html b/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-srcdoc-child.html
new file mode 100644
index 0000000000..cd4b4ae724
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-srcdoc-child.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Referrer Policy: iframes srdoc child correctly inherit the ancestor's referrer policy</title>
+ <link rel="help" href="https://www.w3.org/TR/referrer-policy/#referrer-policy-delivery-nested">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="resources/make-html-script.js"></script>
+ <meta name="referrer" content="origin">
+ </head>
+ <body onload="runTest()">
+ <h1>Referrer Policy: iframes srcdoc child correctly inherit the ancestor's referrer policy</h1>
+ <script>
+ var test = async_test("iframes srcdoc child correctly inherit the ancestor's referrer policy");
+ window.addEventListener("message", test.step_func_done(msg => {
+ assert_equals(msg.data.referrer, self.origin + "/");
+ }));
+
+ function runTest() {
+ var iframe = document.createElement("iframe");
+ iframe.srcdoc = `<body><h1>Outer iframe</h1></body>`;
+ iframe.onload = test.step_func(() => {
+ iframe.onload = null;
+ var iframeChild = iframe.contentDocument.createElement("iframe");
+ iframeChild.srcdoc = createScriptString(get_host_info().REMOTE_ORIGIN);
+ iframe.contentDocument.body.appendChild(iframeChild);
+ });
+ document.body.appendChild(iframe);
+ }
+ </script>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-srcdoc.html b/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-srcdoc.html
new file mode 100644
index 0000000000..6904374b63
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/inheritance/iframe-inheritance-srcdoc.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Referrer Policy: iframes srdoc correctly inherit the ancestor's referrer policy</title>
+ <link rel="help" href="https://www.w3.org/TR/referrer-policy/#referrer-policy-delivery-nested">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="resources/make-html-script.js"></script>
+ <meta name="referrer" content="origin">
+ </head>
+ <body>
+ <h1>Referrer Policy: iframes srcdoc correctly inherit the ancestor's referrer policy</h1>
+ <script>
+ let reportedReferrer = () => {
+ return new Promise(resolve => {
+ window.addEventListener("message", msg => resolve(msg.data.referrer));
+ });
+ };
+
+ const iframe = document.createElement("iframe");
+
+ promise_test(async t => {
+ let referrer = reportedReferrer();
+ iframe.srcdoc = createScriptString(get_host_info().REMOTE_ORIGIN,
+ location.origin + "/custom");
+ document.body.appendChild(iframe);
+ assert_equals(await referrer, self.origin + "/",
+ "Referrer policy should be inherited from parent.");
+
+ let meta = document.createElement('meta');
+ meta.name = "referrer";
+ meta.content = "unsafe-url";
+ document.head.appendChild(meta);
+ iframe.contentWindow.postMessage('checkReferrer');
+ assert_equals(
+ await reportedReferrer(), self.origin + "/",
+ "Changing parent's referrer policy has no effect on the child.");
+
+ }, "Srcdoc iframe inherits referrer policy from parent on creation.");
+
+ </script>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/inheritance/popup-inheritance-about-blank.html b/testing/web-platform/tests/referrer-policy/generic/inheritance/popup-inheritance-about-blank.html
new file mode 100644
index 0000000000..c8e9a9c012
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/inheritance/popup-inheritance-about-blank.html
@@ -0,0 +1,105 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Referrer Policy: popup src="about:blank"</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name="referrer" content="origin">
+<body>
+<script>
+const testFetchClientReferrer =
+ async_test("The fetch() API in an about:blank popup with the 'client' " +
+ "referrer is fetched with no 'Referer' header");
+const testFetchURLReferrer =
+ async_test("The fetch() API in an about:blank popup with a custom URL " +
+ "referrer is fetched with a 'Referer` header that uses the " +
+ "outer document's URL along with its referrer policy");
+const testDocumentReferrer =
+ async_test("The value of document.referrer in an about:blank popup is the " +
+ "outer document's full URL, regardless of referrer policy");
+const testSubresource =
+ async_test("A subresource fetched from an about:blank popup is fetched " +
+ "with no 'Referer' header");
+
+window.addEventListener("message", msg => {
+ const test_name = msg.data.test;
+ const referrer = msg.data.referrer;
+ if (test_name === "testFetchClientReferrer") {
+ // Because the URL of the document of the popup opened through
+ // `window.open()` is "about:blank", the stripped URL is no referrer:
+ // https://w3c.github.io/webappsec-referrer-policy/#strip-url.
+ testFetchClientReferrer.step_func_done(() => {
+ assert_equals(referrer, undefined);
+ })();
+ } else if (test_name === "testFetchURLReferrer") {
+ // The "about:blank" popup inherits its opener's referrer policy.
+ // Note: Setting an explicit URL as referrer is allowed per spec because the
+ // same-origin check at https://fetch.spec.whatwg.org/#dom-request is done
+ // against the popup's origin, which inherits the opener document's origin.
+ testFetchURLReferrer.step_func_done(() => {
+ assert_equals(referrer, location.origin + '/');
+ })();
+ } else if (test_name === "testDocumentReferrer") {
+ // The referrer of the initial document in an about:blank popup is set to
+ // its creating document's URL, unredacted by a referrer policy, as per step
+ // 17 of:
+ // https://html.spec.whatwg.org/multipage/browsers.html#creating-a-new-browsing-context.
+ testDocumentReferrer.step_func_done(() => {
+ assert_equals(referrer, location.href);
+ })();
+ } else if (test_name === "testSubresource") {
+ // Because the URL of the document of the popup is "about:blank", the
+ // stripped URL is no referrer:
+ // https://w3c.github.io/webappsec-referrer-policy/#strip-url.
+ //
+ // Note: this test is essentially the same as "testFetchClientReferrer" (the
+ // only difference is that the fetch is not initiated by javascript).
+ // Compared to the other test, we expect the empty string here instead of
+ // `undefined` just because of a testing quirk.
+ testSubresource.step_func_done(() => {
+ assert_equals(referrer, "");
+ })();
+ }
+});
+
+const popup = window.open();
+const script = popup.document.createElement('script');
+
+script.textContent = `
+ // Test fetch() API with default "client" referrer.
+ fetch("${location.origin}/common/security-features/subresource/xhr.py?name=testFetchClientReferrer")
+ .then(r => r.json())
+ .then(j => {
+ opener.postMessage({test: "testFetchClientReferrer", referrer: j.headers.referer}, "*")
+ }).catch(e => {
+ opener.postMessage({test: "testFetchClientReferrer", referrer: "FAILURE"}, "*");
+ });
+
+ // Test fetch() API with custom URL referrer.
+ fetch("${location.origin}/common/security-features/subresource/xhr.py?name=URL",
+ {referrer: "${location.href}/custom"})
+ .then(r => r.json())
+ .then(j => {
+ opener.postMessage({test: "testFetchURLReferrer", referrer: j.headers.referer}, "*")
+ }).catch(e => {
+ opener.postMessage({test: "testFetchURLReferrer", referrer: "FAILURE"}, "*");
+ });
+
+ // Test document.referrer.
+ opener.postMessage({test: "testDocumentReferrer", referrer: document.referrer}, "*");
+
+ // Test a subresource being fetched by the popup.
+ // This is practicallty the same as the first test: the only difference is
+ // that here the fetch is not triggered by a javascript fetch function but by
+ // a script element with a src tag embedded in the html source.
+ const subresource_script = document.createElement('script');
+ subresource_script.src = "${location.origin}/common/security-features/subresource/referrer.py";
+ subresource_script.onload = e => {
+ opener.postMessage({test: "testSubresource", referrer: window.referrer}, "*");
+ }
+ subresource_script.onerror = function(e) {
+ opener.postMessage({test: "testSubresource", referrer: "FAILURE"}, "*");
+ };
+ document.head.appendChild(subresource_script);
+`;
+popup.document.body.appendChild(script);
+</script>
diff --git a/testing/web-platform/tests/referrer-policy/generic/inheritance/popup-inheritance-form-submission.html b/testing/web-platform/tests/referrer-policy/generic/inheritance/popup-inheritance-form-submission.html
new file mode 100644
index 0000000000..2c03792a07
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/inheritance/popup-inheritance-form-submission.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Referrer Policy: popup src="about:blank"</title>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1370425">
+<link rel="help" href="https://html.spec.whatwg.org/#creating-a-new-browsing-context">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+
+<iframe src="resources/submit-form-and-remove-frame.html"></iframe>
+<script>
+async_test(t => {
+ // Called by the child frame once it has submitted its form that creates a new
+ // `about:blank` window in our browsing context group (therefore, the window
+ // is reachable by us).
+ window.removeIframe = t.step_func(() => {
+ const iframe = document.querySelector('iframe');
+ const expected_referrer = iframe.contentWindow.location.href;
+ iframe.remove();
+
+ // The child frame is removed, but its form submission navigation is still
+ // queued on the opened window's global. Wait until it is run and then
+ // evaluate script.
+ t.step_timeout(t.step_func_done(() => {
+ const window_opened_from_form = window.open("", "does-not-exist");
+ assert_equals(document.referrer, expected_referrer);
+ }));
+ });
+}, "A new frame's document.referrer is correct even if its initiator frame is gone");
+</script>
diff --git a/testing/web-platform/tests/referrer-policy/generic/inheritance/resources/make-html-script.js b/testing/web-platform/tests/referrer-policy/generic/inheritance/resources/make-html-script.js
new file mode 100644
index 0000000000..6c2c145c4e
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/inheritance/resources/make-html-script.js
@@ -0,0 +1,19 @@
+function createScriptString(origin, referrer) {
+ let request_init = referrer ? `{referrer: "${referrer}"}` : "";
+ return `<script>
+ function checkReferrer() {
+ fetch("${origin}/common/security-features/subresource/xhr.py",
+ ${request_init})
+ .then(r => r.json())
+ .then(j => {
+ top.postMessage({referrer: j.headers.referer}, "*")
+ }).catch(e => {
+ top.postMessage({referrer: "FAILURE"}, "*");
+ });
+ }
+ checkReferrer();
+ window.addEventListener("message", msg => {
+ if (msg.data === "checkReferrer") checkReferrer();
+ });
+ <\/script>`;
+}
diff --git a/testing/web-platform/tests/referrer-policy/generic/inheritance/resources/submit-form-and-remove-frame.html b/testing/web-platform/tests/referrer-policy/generic/inheritance/resources/submit-form-and-remove-frame.html
new file mode 100644
index 0000000000..bf5ede96d9
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/inheritance/resources/submit-form-and-remove-frame.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<meta name='referrer' content='no-referrer'>
+<body onload='start()'>
+<script>
+ function start() {
+ myform.submit();
+ parent.removeIframe();
+ }
+</script>
+<form id='myform' action='about:blank' target='does-not-exist'>
diff --git a/testing/web-platform/tests/referrer-policy/generic/inheritance/workers.html b/testing/web-platform/tests/referrer-policy/generic/inheritance/workers.html
new file mode 100644
index 0000000000..0bd75a1d15
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/inheritance/workers.html
@@ -0,0 +1,47 @@
+<html>
+ <head>
+ <title>Referrer Policy: local scheme workers inherit from creator</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+ <meta name="referrer" content="no-referrer">
+ </head>
+ <script>
+ let cross_origin = get_host_info().REMOTE_ORIGIN;
+
+ let generateFetchString = postmessage => `
+ fetch("${cross_origin}/common/security-features/subresource/xhr.py",
+ {referrer: "${location.href}/custom"})
+ .then(r => r.json())
+ .then(j => ${postmessage}({referrer: j.headers.referer}))
+ .catch(e => ${postmessage}({referrer: "FAILURE"}));`
+
+ async_test(t => {
+ let blob = new Blob([generateFetchString("postMessage")],
+ {type : 'application/javascript'});
+ let blob_url = URL.createObjectURL(blob);
+ let worker = new Worker(blob_url);
+ worker.onmessage = t.step_func_done(msg => {
+ assert_equals(msg.data.referrer, undefined);
+ });
+ }, "Dedicated worker with local scheme inherits referrer policy " +
+ "from the creating document.");
+
+ async_test(t => {
+ let script = `
+ onconnect = e => {
+ let port = e.ports[0];
+ port.start();
+ ${generateFetchString("port.postMessage")}
+ };`
+ let blob = new Blob([script], {type : 'application/javascript'});
+ let blob_url = URL.createObjectURL(blob);
+ let shared_worker = new SharedWorker(blob_url);
+ shared_worker.port.start();
+ shared_worker.port.onmessage = t.step_func_done(msg => {
+ assert_equals(msg.data.referrer, undefined);
+ });
+ }, "Shared worker with local scheme inherits referrer policy " +
+ "from the creating document.");
+ </script>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/link-rel-prefetch.html b/testing/web-platform/tests/referrer-policy/generic/link-rel-prefetch.html
new file mode 100644
index 0000000000..72e831c921
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/link-rel-prefetch.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Referrer policies for resources loaded via link rel prefetch</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- Common global functions for referrer-policy tests. -->
+ <script src="/common/security-features/resources/common.sub.js"></script>
+ <meta name="referrer" content="origin">
+ <link rel="prefetch" href="/common/security-features/subresource/image.py">
+ </head>
+ <body>
+ <p>Check that resources loaded via link rel prefetch use the referrer
+ and referrer policy from the document.</p>
+
+ <script>
+ var img_url = "/common/security-features/subresource/image.py";
+ promise_test((t) => timeoutPromise(t, 1000)
+ .then(() => requestViaImage(img_url, null))
+ .then(message => {
+ assert_equals(message.headers.referer, document.location.origin + "/");
+ }),
+ "Prefetched image.");
+ </script>
+
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/meta-referrer-outofhead-fetch.http.html b/testing/web-platform/tests/referrer-policy/generic/meta-referrer-outofhead-fetch.http.html
new file mode 100644
index 0000000000..1b7a7bada5
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/meta-referrer-outofhead-fetch.http.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <meta name="referrer" content="no-referrer">
+ <script>
+ promise_test((t) =>
+ fetch("/common/security-features/subresource/xhr.py")
+ .then(res => res.json())
+ .then(data => {
+ assert_equals(data.headers.referer, undefined);
+ }),
+ "Referer header was not send");
+ </script>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/meta-referrer-removed-1.http.html b/testing/web-platform/tests/referrer-policy/generic/meta-referrer-removed-1.http.html
new file mode 100644
index 0000000000..7027788504
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/meta-referrer-removed-1.http.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+
+ <meta name="referrer" content="no-referrer" id="referrermeta">
+</head>
+<body>
+ <script>
+ async function fetchAndGetReferrer() {
+ let response = await fetch('/common/security-features/subresource/xhr.py');
+ let data = await response.json();
+ return data.headers.referer;
+ }
+
+ promise_test(async t => {
+ assert_equals(await fetchAndGetReferrer(), undefined,
+ 'referrer should not be set');
+
+ document.getElementById('referrermeta').remove();
+ assert_equals(await fetchAndGetReferrer(), undefined,
+ 'referrer should not be set');
+ }, 'removing <meta name="referrer"> should not change referrer policy');
+ </script>
+</body>
diff --git a/testing/web-platform/tests/referrer-policy/generic/meta-referrer-removed-2.http.html b/testing/web-platform/tests/referrer-policy/generic/meta-referrer-removed-2.http.html
new file mode 100644
index 0000000000..42f73e8781
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/meta-referrer-removed-2.http.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+
+ <meta name="referrer" content="no-referrer" id="referrermeta">
+</head>
+<body>
+ <script>
+ async function fetchAndGetReferrer() {
+ let response = await fetch('/common/security-features/subresource/xhr.py');
+ let data = await response.json();
+ return data.headers.referer;
+ }
+
+ promise_test(async t => {
+ assert_equals(await fetchAndGetReferrer(), undefined,
+ 'referrer should not be set');
+
+ // Add second meta tag.
+ const second_meta = document.createElement('meta');
+ second_meta.name = 'referrer';
+ second_meta.content = 'strict-origin';
+ document.head.appendChild(second_meta);
+ // Second meta should override the first.
+ assert_equals(await fetchAndGetReferrer(), location.origin + '/',
+ 'referrer should be origin only');
+
+ second_meta.remove();
+ assert_equals(await fetchAndGetReferrer(), window.location.origin + '/',
+ 'referrer should be origin only');
+ }, 'referrer policy does not change when second <meta name="referrer"> is removed');
+ </script>
+</body>
diff --git a/testing/web-platform/tests/referrer-policy/generic/meta-tag-in-svg-image.html b/testing/web-platform/tests/referrer-policy/generic/meta-tag-in-svg-image.html
new file mode 100644
index 0000000000..5bdc2c1abf
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/meta-tag-in-svg-image.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Referrer Policy: Meta tag in svg image loaded via img should not change referrer policy</title>
+ <meta name="referrer" content="origin"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- Common global functions for referrer-policy tests. -->
+ <script src="/common/security-features/resources/common.sub.js"></script>
+ </head>
+ <body>
+ <script>
+ async_test(function(t) {
+ var img = document.createElement("img");
+ img.onload = function() {
+ var urlPath = '/common/security-features/subresource/image.py?cache_destroyer=' + (new Date()).getTime();
+ return requestViaImage(urlPath, null, 'always')
+ .then(t.step_func(function(message) {
+ assert_equals(message.referrer, self.origin + '/');
+ }))
+ .finally(function() { t.done(); });
+ };
+ img.onerror = t.step_func_done(function() {
+ assert_unreached("img should load");
+ });
+ img.src = "./resources/img-with-referrer-policy.svg";
+ document.body.appendChild(img);
+ }, "Meta tag in SVG image loaded via img should be ignored");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/multiple-headers-and-values.html b/testing/web-platform/tests/referrer-policy/generic/multiple-headers-and-values.html
new file mode 100644
index 0000000000..e6b7b07d51
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/multiple-headers-and-values.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Referrer Policy: multiple Referrer-Policy header and header values are allowed</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+
+ <script src="/common/security-features/resources/common.sub.js"></script>
+ </head>
+ <body>
+ <h1>Referrer Policy: multiple Referrer-Policy header and header values are allowed</h1>
+ <p></p>
+
+ <pre id="received_message">Running...</pre>
+
+ <script>
+ promise_test(() => {
+ var urlPath = '/common/security-features/subresource/image.py?cache_destroyer=' + (new Date()).getTime();
+ var url = location.protocol + "//www1." + location.hostname + ":" + location.port +
+ urlPath;
+ return requestViaImage(url, null, 'no-referrer')
+ .then(function(message) {
+ assert_equals(message.referrer, document.location.origin + "/");
+ });
+ }, "Image uses the last recognized Referrer-Policy header value");
+ </script>
+
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/multiple-headers-and-values.html.headers b/testing/web-platform/tests/referrer-policy/generic/multiple-headers-and-values.html.headers
new file mode 100644
index 0000000000..d1acc2f1d3
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/multiple-headers-and-values.html.headers
@@ -0,0 +1,2 @@
+Referrer-Policy: no-referrer
+Referrer-Policy: no-referrer,origin
diff --git a/testing/web-platform/tests/referrer-policy/generic/multiple-headers-combined.html b/testing/web-platform/tests/referrer-policy/generic/multiple-headers-combined.html
new file mode 100644
index 0000000000..b5c27515df
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/multiple-headers-combined.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Referrer Policy: multiple Referrer-Policy header values are allowed</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+
+ <script src="/common/security-features/resources/common.sub.js"></script>
+ </head>
+ <body>
+ <h1>Referrer Policy: multiple Referrer-Policy header values are allowed</h1>
+ <p></p>
+
+ <pre id="received_message">Running...</pre>
+
+ <script>
+ promise_test(() => {
+ var urlPath = '/common/security-features/subresource/image.py?cache_destroyer=' + (new Date()).getTime();
+ var url = location.protocol + "//www1." + location.hostname + ":" + location.port +
+ urlPath;
+ return requestViaImage(url, null, 'no-referrer')
+ .then(function(message) {
+ assert_equals(message.referrer, document.location.origin + "/");
+ });
+ }, "Image uses the last recognized Referrer-Policy header value");
+ </script>
+
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/multiple-headers-combined.html.headers b/testing/web-platform/tests/referrer-policy/generic/multiple-headers-combined.html.headers
new file mode 100644
index 0000000000..fc30a2a186
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/multiple-headers-combined.html.headers
@@ -0,0 +1 @@
+Referrer-Policy: no-referrer, origin
diff --git a/testing/web-platform/tests/referrer-policy/generic/multiple-headers-one-invalid.html b/testing/web-platform/tests/referrer-policy/generic/multiple-headers-one-invalid.html
new file mode 100644
index 0000000000..eca734601a
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/multiple-headers-one-invalid.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Referrer Policy: multiple Referrer-Policy headers with one invalid</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+
+ <script src="/common/security-features/resources/common.sub.js"></script>
+ </head>
+ <body>
+ <h1>Referrer Policy: multiple Referrer-Policy headers with one invalid</h1>
+ <p></p>
+
+ <pre id="received_message">Running...</pre>
+
+ <script>
+ promise_test(() => {
+ var urlPath = '/common/security-features/subresource/image.py?cache_destroyer=' + (new Date()).getTime();
+ // The default referrer policy is strict-origin-when-cross-origin.
+ // This document's headers contain the 'origin' and 'no-referrer' tokens,
+ // and we're making a same-origin image load, so, if the image request,
+ // uses the default policy (which is what this test's verifying), we
+ // should see the full initiating URL in the referrer, rather than just
+ // the origin or an empty string.
+ return requestViaImage(urlPath, null, 'no-referrer')
+ .then(function(message) {
+ assert_equals(message.referrer, document.location.href);
+ });
+ }, "Referrer policy header parsing fails if one header is invalid");
+ </script>
+
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/multiple-headers-one-invalid.html.headers b/testing/web-platform/tests/referrer-policy/generic/multiple-headers-one-invalid.html.headers
new file mode 100644
index 0000000000..0752193804
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/multiple-headers-one-invalid.html.headers
@@ -0,0 +1,2 @@
+Referrer-Policy: origin
+Referrer-Policy: origin no-referrer
diff --git a/testing/web-platform/tests/referrer-policy/generic/multiple-headers-one-unknown-token.html b/testing/web-platform/tests/referrer-policy/generic/multiple-headers-one-unknown-token.html
new file mode 100644
index 0000000000..f07500e546
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/multiple-headers-one-unknown-token.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Referrer Policy: multiple Referrer-Policy headers with one invalid</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+
+ <script src="/common/security-features/resources/common.sub.js"></script>
+ </head>
+ <body>
+ <h1>Referrer Policy: multiple Referrer-Policy headers with one invalid</h1>
+ <p></p>
+
+ <pre id="received_message">Running...</pre>
+
+ <script>
+ promise_test(() => {
+ var urlPath = '/common/security-features/subresource/image.py?cache_destroyer=' + (new Date()).getTime();
+ var url = location.protocol + "//www1." + location.hostname + ":" + location.port +
+ urlPath;
+ return requestViaImage(url, null, 'no-referrer')
+ .then(function(message) {
+ assert_equals(message.referrer, document.location.origin + "/");
+ });
+ }, "Image uses last recognized referrer policy token from Referrer-Policy headers");
+ </script>
+
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/multiple-headers-one-unknown-token.html.headers b/testing/web-platform/tests/referrer-policy/generic/multiple-headers-one-unknown-token.html.headers
new file mode 100644
index 0000000000..46feffd705
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/multiple-headers-one-unknown-token.html.headers
@@ -0,0 +1,2 @@
+Referrer-Policy: no-referrer
+Referrer-Policy: origin,not-a-valid-token
diff --git a/testing/web-platform/tests/referrer-policy/generic/multiple-headers.html b/testing/web-platform/tests/referrer-policy/generic/multiple-headers.html
new file mode 100644
index 0000000000..d6c3a90ccb
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/multiple-headers.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Referrer Policy: multiple Referrer-Policy headers are allowed</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+
+ <script src="/common/security-features/resources/common.sub.js"></script>
+ </head>
+ <body>
+ <h1>Referrer Policy: multiple Referrer-Policy headers are allowed</h1>
+ <p></p>
+
+ <pre id="received_message">Running...</pre>
+
+ <script>
+ promise_test(() => {
+ var urlPath = '/common/security-features/subresource/image.py?cache_destroyer=' + (new Date()).getTime();
+ var url = location.protocol + "//www1." + location.hostname + ":" + location.port +
+ urlPath;
+ return requestViaImage(url, null, 'no-referrer')
+ .then(function(message) {
+ assert_equals(message.referrer, document.location.origin + "/");
+ });
+ }, "Image uses the last recognized Referrer-Policy header");
+ </script>
+
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/multiple-headers.html.headers b/testing/web-platform/tests/referrer-policy/generic/multiple-headers.html.headers
new file mode 100644
index 0000000000..dd1dd853f2
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/multiple-headers.html.headers
@@ -0,0 +1,2 @@
+Referrer-Policy: no-referrer
+Referrer-Policy: origin
diff --git a/testing/web-platform/tests/referrer-policy/generic/resources/img-with-referrer-policy.svg b/testing/web-platform/tests/referrer-policy/generic/resources/img-with-referrer-policy.svg
new file mode 100644
index 0000000000..d54232d7bb
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/resources/img-with-referrer-policy.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="100%" height="100%" version="1.1"
+xmlns="http://www.w3.org/2000/svg">
+ <meta xmlns="http://www.w3.org/1999/xhtml" name="referrer" content="unsafe-url"/>
+ <circle cx="10" cy="10" r="10" stroke="black" stroke-width="1" fill="red" />
+</svg> \ No newline at end of file
diff --git a/testing/web-platform/tests/referrer-policy/generic/resources/referrer.py b/testing/web-platform/tests/referrer-policy/generic/resources/referrer.py
new file mode 100644
index 0000000000..2d15dc09c4
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/resources/referrer.py
@@ -0,0 +1,10 @@
+def main(request, response):
+ response_headers = [(b"Access-Control-Allow-Origin", b"*")]
+ body = b"""
+ <p id=referrer>%s</p>
+ <script>
+ const referrer_text = referrer.textContent;
+ window.parent.postMessage(referrer_text, "*");
+ </script>
+ """ % request.headers.get(b"referer", b"")
+ return (200, response_headers, body)
diff --git a/testing/web-platform/tests/referrer-policy/generic/sandboxed-iframe-with-opaque-origin.html b/testing/web-platform/tests/referrer-policy/generic/sandboxed-iframe-with-opaque-origin.html
new file mode 100644
index 0000000000..fd1857e0dd
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/sandboxed-iframe-with-opaque-origin.html
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Referrer Policy: Sandboxed iframes with opaque origins don't send referrers</title>
+ <link rel="author" title="Jochen Eisinger" href="mailto:jochen@chromium.org">
+ <link rel="author" title="Arthur Sonzogni" href="mailto:arthursonzogni@chromium.org">
+ <link rel="help" href="https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- Common global functions for referrer-policy tests. -->
+ <script src="/common/security-features/resources/common.sub.js"></script>
+ <script src="/common/get-host-info.sub.js"></script>
+</head>
+<body>
+<h1>
+ Referrer Policy: A document with an opaque origin doesn't send referrers
+</h1>
+<script>
+
+let futureMessage = function() {
+ return new Promise(resolve => {
+ window.addEventListener("message", event => resolve(event.data));
+ });
+}
+
+function testSandboxedIframeSubresource(description,
+ sandboxAttributes,
+ expectedReferrer) {
+ promise_test(async test => {
+ let resource_url = get_host_info().HTTP_NOTSAMESITE_ORIGIN +
+ "/common/security-features/subresource/xhr.py";
+ const iframe = document.createElement("iframe");
+ iframe.sandbox = sandboxAttributes;
+ iframe.srcdoc = `
+ <meta name="referrer" content="always">
+ <script src="/common/security-features/resources/common.sub.js">
+ </scr`+`ipt>
+ <script>
+ requestViaFetch("${resource_url}").then((msg) => {
+ parent.postMessage(msg.referrer, '*');
+ }).catch((e) => {
+ parent.postMessage("FAILURE", '*');
+ });
+ </scr`+`ipt>
+ `;
+
+ const future_message = futureMessage();
+ document.body.appendChild(iframe);
+ assert_equals(await future_message, expectedReferrer);
+
+ }, description);
+}
+
+function testSandboxedIframeMainResource(description,
+ sandboxAttributes,
+ expectedReferrer) {
+ promise_test(async test => {
+ let document_url = get_host_info().HTTP_NOTSAMESITE_ORIGIN +
+ "/referrer-policy/generic/resources/referrer.py";
+ const iframe = document.createElement("iframe");
+ iframe.sandbox = sandboxAttributes;
+ iframe.srcdoc = `
+ <meta name="referrer" content="always">
+ <script>
+ onload = () => {
+ location.href = "${document_url}";
+ }
+ </scr`+`ipt>
+ `;
+
+ const future_message = futureMessage();
+ document.body.appendChild(iframe);
+ assert_equals(await future_message, expectedReferrer);
+
+ }, description);
+}
+
+testSandboxedIframeSubresource(
+ "Sandboxed iframe with opaque origin doesn't send referrers to subresources",
+ "allow-scripts", undefined);
+testSandboxedIframeSubresource(
+ "Sandboxed iframe with tuple origin sends referrers to subresources",
+ "allow-same-origin allow-scripts", document.location.href);
+testSandboxedIframeMainResource(
+ "Sandboxed iframe with opaque origin doesn't send referrers on navigation",
+ "allow-scripts", "");
+testSandboxedIframeMainResource(
+ "Sandboxed iframe with tuple origin sends referrers on navigation",
+ "allow-same-origin allow-scripts", document.location.href);
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/sanity-checker.js b/testing/web-platform/tests/referrer-policy/generic/sanity-checker.js
new file mode 100644
index 0000000000..e296ce93b9
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/sanity-checker.js
@@ -0,0 +1,46 @@
+// The SanityChecker is used in debug mode to identify problems with the
+// structure of the testsuite. In release mode it is mocked out to do nothing.
+
+function SanityChecker() {}
+
+SanityChecker.prototype.checkScenario = function(scenario) {
+ // Check if scenario is valid.
+ // TODO(kristijanburnik): Move to a sanity-checks.js for debug mode only.
+ test(function() {
+
+ // We extend the exsiting test_expansion_schema not to kill performance by
+ // copying.
+ var expectedFields = SPEC_JSON["test_expansion_schema"];
+ expectedFields["referrer_policy"] = SPEC_JSON["referrer_policy_schema"];
+
+ for (var field in expectedFields) {
+ assert_own_property(scenario, field,
+ "The scenario contains field " + field)
+ assert_in_array(scenario[field], expectedFields[field],
+ "Scenario's " + field + " is one of: " +
+ expectedFields[field].join(", ")) + "."
+ }
+
+ // Check if the protocol is matched.
+ assert_equals(scenario["source_protocol"] + ":", location.protocol,
+ "Protocol of the test page should match the scenario.")
+
+ }, "[ReferrerPolicyTestCase] The test scenario is valid.");
+}
+
+SanityChecker.prototype.checkSubresourceResult = function(scenario,
+ subresourceUrl,
+ result) {
+ assert_equals(Object.keys(result).length, 3);
+ assert_own_property(result, "location");
+ assert_own_property(result, "referrer");
+ assert_own_property(result, "headers");
+
+ // Skip location check for scripts.
+ if (scenario.subresource == "script-tag")
+ return;
+
+ // Sanity check: location of sub-resource matches reported location.
+ assert_equals(result.location, subresourceUrl,
+ "Subresource reported location.");
+};
diff --git a/testing/web-platform/tests/referrer-policy/generic/second-meta-referrer-added-before-first.http.html b/testing/web-platform/tests/referrer-policy/generic/second-meta-referrer-added-before-first.http.html
new file mode 100644
index 0000000000..38fab901fb
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/second-meta-referrer-added-before-first.http.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+
+ <meta name="referrer" content="no-referrer" id="referrermeta">
+</head>
+<body>
+ <script>
+ async function fetchAndGetReferrer() {
+ let response = await fetch('/common/security-features/subresource/xhr.py');
+ let data = await response.json();
+ return data.headers.referer;
+ }
+
+ promise_test(async t => {
+ assert_equals(await fetchAndGetReferrer(), undefined,
+ 'referrer should not be set');
+
+ // Add second meta _before_ first meta.
+ const first_meta = document.getElementById('referrermeta');
+ const second_meta = document.createElement('meta');
+ second_meta.name = 'referrer';
+ second_meta.content = 'strict-origin';
+ document.head.insertBefore(second_meta, first_meta);
+ assert_equals(await fetchAndGetReferrer(), window.location.origin + '/',
+ 'referrer should the origin only');
+ }, 'document referrer policy is the value of the most recently added <meta name="referrer">');
+
+ </script>
+</body>
diff --git a/testing/web-platform/tests/referrer-policy/generic/subresource-test/area-navigate.html b/testing/web-platform/tests/referrer-policy/generic/subresource-test/area-navigate.html
new file mode 100644
index 0000000000..2a4f29654d
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/subresource-test/area-navigate.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- TODO(kristijanburnik): Remove subres. duplication. Reuse a template. -->
+<html>
+ <head>
+ <title>Area Link messaging - cross-origin Area Link navigation</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- Common global functions for referrer-policy tests. -->
+ <script src="/common/security-features/resources/common.sub.js"></script>
+ </head>
+ <body>
+ <h1>Area Link messaging - cross-origin Area Link navigation</h1>
+ <p>If you can read JSON encoded HTTP request headers of the Area link below,
+ the messaging works as expected.</p>
+
+ <pre id="received_message">Running...</pre>
+
+ <script>
+ promise_test(function() {
+ var urlPath = '/common/security-features/subresource/document.py';
+ var url = location.protocol + "//www1." + location.hostname + ":" + location.port +
+ urlPath;
+ return requestViaArea(url)
+ .then(function(message) {
+ var pre = document.getElementById('received_message')
+ var headers = message.headers;
+ pre.innerHTML = "";
+ pre.innerHTML += url + ":\n\n";
+ pre.innerHTML += JSON.stringify(headers, null, 2) + "\n\n"
+ assert_own_property(headers, "host")
+ assert_own_property(headers, "connection")
+ });
+ },
+ "Area is responding with HTTP headers");
+ </script>
+
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/subresource-test/attr-referrer-invalid-value.html b/testing/web-platform/tests/referrer-policy/generic/subresource-test/attr-referrer-invalid-value.html
new file mode 100644
index 0000000000..bfdf1166ce
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/subresource-test/attr-referrer-invalid-value.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Invalid referrerPolicy attribute value</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <h1>Invalid referrerPolicy attribute value</h1>
+ <pre>Running...</pre>
+
+ <script>
+ test(function () {
+ var elements = ["iframe", "img", "a", "area", "link", "script"];
+ for (var i = 0; i < elements.length; i++) {
+ var elem = document.createElement(elements[i]);
+ elem.referrerPolicy = "unsafe-url";
+ assert_equals(elem.referrerPolicy, "unsafe-url");
+ elem.referrerPolicy = "not-valid-value";
+ assert_equals(elem.referrerPolicy, "");
+ }
+ }, "Invalid referrerpolicy values not reflected");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/subresource-test/fetch-messaging.html b/testing/web-platform/tests/referrer-policy/generic/subresource-test/fetch-messaging.html
new file mode 100644
index 0000000000..2678af822e
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/subresource-test/fetch-messaging.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- TODO(kristijanburnik): Remove subres. duplication. Reuse a template. -->
+<html>
+ <head>
+ <title>Fetch messaging - same-origin Fetch request</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- Common global functions for referrer-policy tests. -->
+ <script src="/common/security-features/resources/common.sub.js"></script>
+ </head>
+ <body>
+ <h1>Fetch messaging - same-origin Fetch request</h1>
+ <p>If you can read JSON encoded HTTP request headers of the Fetch below,
+ the messaging works as expected.</p>
+
+ <pre id="received_message">Running...</pre>
+
+ <script>
+ test(function() {
+ assert_true(!!window.fetch, "Fetch is not supported by this browser.");
+ }, "Fetch is supported by the browser.");
+
+ promise_test(function() {
+ var urlPath = '/common/security-features/subresource/xhr.py';
+ var url = location.protocol + "//" + location.hostname + ":" +
+ location.port + urlPath;
+ return requestViaFetch(url)
+ .then(function(message) {
+ var pre = document.getElementById('received_message')
+ var headers = message.headers;
+ pre.innerHTML = "";
+ pre.innerHTML += url + ":\n\n";
+ pre.innerHTML += JSON.stringify(headers, null, 2) + "\n\n";
+ assert_own_property(headers, "host")
+ assert_own_property(headers, "connection")
+ });
+ }, "Fetch is responding with HTTP headers");
+ </script>
+
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/subresource-test/iframe-messaging.html b/testing/web-platform/tests/referrer-policy/generic/subresource-test/iframe-messaging.html
new file mode 100644
index 0000000000..b8bdb0e5e0
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/subresource-test/iframe-messaging.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- TODO(kristijanburnik): Remove subres. duplication. Reuse a template. -->
+<html>
+ <head>
+ <title>Iframe messaging - cross-origin iframe request</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- Common global functions for referrer-policy tests. -->
+ <script src="/common/security-features/resources/common.sub.js"></script>
+ </head>
+ <body>
+ <h1>Iframe messaging - cross-origin iframe request</h1>
+ <p>If you can read JSON encoded HTTP request headers of the iframe below,
+ the messaging works as expected.</p>
+
+ <pre id="received_message">Running...</pre>
+
+ <script>
+ promise_test(function() {
+ var urlPath = '/common/security-features/subresource/document.py';
+ var url = location.protocol + "//www1." + location.hostname + ":" + location.port +
+ urlPath;
+ return requestViaIframe(url)
+ .then(function(message) {
+ var pre = document.getElementById('received_message')
+ var headers = message.headers;
+ pre.innerHTML = "";
+ pre.innerHTML += url + ":\n\n";
+ pre.innerHTML += JSON.stringify(headers, null, 2) + "\n\n"
+ assert_own_property(headers, "host")
+ assert_own_property(headers, "connection")
+ });
+ }, "Iframe is responding with HTTP headers");
+ </script>
+
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/subresource-test/image-decoding.html b/testing/web-platform/tests/referrer-policy/generic/subresource-test/image-decoding.html
new file mode 100644
index 0000000000..76ce0e263a
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/subresource-test/image-decoding.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- TODO(kristijanburnik): Remove subres. duplication. Reuse a template. -->
+<html>
+ <head>
+ <title>Image decoding - cross-origin image request</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- Common global functions for referrer-policy tests. -->
+ <script src="/common/security-features/resources/common.sub.js"></script>
+ </head>
+ <body>
+ <h1>Image decoding - cross-origin image request</h1>
+ <p>If you can read JSON encoded HTTP headers of the image below,
+ the decoding works as expected.</p>
+
+ <pre id="received_message">Running...</pre>
+
+ <script>
+ promise_test(function() {
+ var urlPath = '/common/security-features/subresource/image.py';
+ var url = location.protocol + "//www1." + location.hostname + ":" + location.port +
+ urlPath + "?cache_destroyer=" + (new Date()).getTime();
+ return requestViaImage(url, undefined, "always")
+ .then(function(message) {
+ var pre = document.getElementById('received_message')
+ var headers = message.headers;
+ pre.innerHTML = "";
+ pre.innerHTML += url + ":\n\n";
+ pre.innerHTML += JSON.stringify(headers, null, 2) + "\n\n"
+ assert_own_property(headers, "host")
+ assert_own_property(headers, "connection")
+ });
+ }, "Image is encoding headers as JSON.");
+ </script>
+
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/subresource-test/link-navigate.html b/testing/web-platform/tests/referrer-policy/generic/subresource-test/link-navigate.html
new file mode 100644
index 0000000000..21783d3e31
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/subresource-test/link-navigate.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- TODO(kristijanburnik): Remove subres. duplication. Reuse a template. -->
+<html>
+ <head>
+ <title>Link messaging - cross-origin Link navigation</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- Common global functions for referrer-policy tests. -->
+ <script src="/common/security-features/resources/common.sub.js"></script>
+ </head>
+ <body>
+ <h1>Link messaging - cross-origin Link navigation</h1>
+ <p>If you can read JSON encoded HTTP request headers of the Link below,
+ the messaging works as expected.</p>
+
+ <pre id="received_message">Running...</pre>
+
+ <script>
+ promise_test(function() {
+ var urlPath = '/common/security-features/subresource/document.py';
+ var url = location.protocol + "//www1." + location.hostname + ":" + location.port +
+ urlPath;
+ return requestViaAnchor(url)
+ .then(function(message) {
+ var pre = document.getElementById('received_message')
+ var headers = message.headers;
+ pre.innerHTML = "";
+ pre.innerHTML += url + ":\n\n";
+ pre.innerHTML += JSON.stringify(headers, null, 2) + "\n\n"
+ assert_own_property(headers, "host")
+ assert_own_property(headers, "connection")
+ });
+ }, "Link is responding with HTTP headers");
+ </script>
+
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/subresource-test/script-messaging.html b/testing/web-platform/tests/referrer-policy/generic/subresource-test/script-messaging.html
new file mode 100644
index 0000000000..1bc0ba13ef
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/subresource-test/script-messaging.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- TODO(kristijanburnik): Remove subres. duplication. Reuse a template. -->
+<html>
+ <head>
+ <title>Script messaging - cross-origin Script request</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- Common global functions for referrer-policy tests. -->
+ <script src="/common/security-features/resources/common.sub.js"></script>
+ </head>
+ <body>
+ <h1>Script messaging - cross-origin Script request</h1>
+ <p>If you can read JSON encoded HTTP request headers of the Script below,
+ the messaging works as expected.</p>
+
+ <pre id="received_message">Running...</pre>
+
+ <script>
+ promise_test(function() {
+ var urlPath = '/common/security-features/subresource/script.py';
+ var url = location.protocol + "//www1." + location.hostname + ":" + location.port +
+ urlPath;
+ return requestViaScript(url)
+ .then(function(message) {
+ var pre = document.getElementById('received_message')
+ var headers = message.headers;
+ pre.innerHTML = "";
+ pre.innerHTML += url + ":\n\n";
+ pre.innerHTML += JSON.stringify(headers, null, 2) + "\n\n"
+ assert_own_property(headers, "host")
+ assert_own_property(headers, "connection")
+ });
+ }, "Script is responding with HTTP headers");
+ </script>
+
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/subresource-test/worker-messaging.html b/testing/web-platform/tests/referrer-policy/generic/subresource-test/worker-messaging.html
new file mode 100644
index 0000000000..c2db8fe845
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/subresource-test/worker-messaging.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- TODO(kristijanburnik): Remove subres. duplication. Reuse a template. -->
+<html>
+ <head>
+ <title>Worker messaging - same-origin Worker request</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- Common global functions for referrer-policy tests. -->
+ <script src="/common/security-features/resources/common.sub.js"></script>
+ </head>
+ <body>
+ <h1>Worker messaging - same-origin Worker request</h1>
+ <p>If you can read JSON encoded HTTP request headers of the Worker below,
+ the messaging works as expected.</p>
+
+ <pre id="received_message">Running...</pre>
+
+ <script>
+ promise_test(function() {
+ var urlPath = '/common/security-features/subresource/worker.py';
+ var url = location.protocol + "//" + location.hostname + ":" +
+ location.port + urlPath;
+ return requestViaDedicatedWorker(url, {})
+ .then(function(message) {
+ var pre = document.getElementById('received_message')
+ var headers = message.headers;
+ pre.innerHTML = "";
+ pre.innerHTML += url + ":\n\n";
+ pre.innerHTML += JSON.stringify(headers, null, 2) + "\n\n"
+ assert_own_property(headers, "host")
+ assert_own_property(headers, "connection")
+ });
+ }, "Worker is responding with HTTP headers");
+ </script>
+
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/subresource-test/xhr-messaging.html b/testing/web-platform/tests/referrer-policy/generic/subresource-test/xhr-messaging.html
new file mode 100644
index 0000000000..c1f89919ca
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/subresource-test/xhr-messaging.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- TODO(kristijanburnik): Remove subres. duplication. Reuse a template. -->
+<html>
+ <head>
+ <title>XHR messaging - cross-origin XHR request</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- Common global functions for referrer-policy tests. -->
+ <script src="/common/security-features/resources/common.sub.js"></script>
+ </head>
+ <body>
+ <h1>XHR messaging - cross-origin XHR request</h1>
+ <p>If you can read JSON encoded HTTP request headers of the XHR below,
+ the messaging works as expected.</p>
+
+ <pre id="received_message">Running...</pre>
+
+ <script>
+ promise_test(function() {
+ var urlPath = '/common/security-features/subresource/xhr.py';
+ var url = location.protocol + "//www1." + location.hostname + ":" + location.port +
+ urlPath;
+ return requestViaXhr(url)
+ .then(function(message) {
+ var pre = document.getElementById('received_message')
+ var headers = message.headers;
+ pre.innerHTML = "";
+ pre.innerHTML += url + ":\n\n";
+ pre.innerHTML += JSON.stringify(headers, null, 2) + "\n\n"
+ assert_own_property(headers, "host")
+ assert_own_property(headers, "connection")
+ });
+ }, "XHR is responding with HTTP headers");
+ </script>
+
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/referrer-policy/generic/test-case.sub.js b/testing/web-platform/tests/referrer-policy/generic/test-case.sub.js
new file mode 100644
index 0000000000..717cd1a5e7
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/test-case.sub.js
@@ -0,0 +1,127 @@
+// https://w3c.github.io/webappsec-referrer-policy/#strip-url
+function stripUrlForUseAsReferrer(url, originOnly) {
+ // Step 2. If url’s scheme is a local scheme, then return no referrer.
+ const parsedUrl = new URL(url);
+
+ if (["about:", "blob:", "data:"].includes(parsedUrl.protocol))
+ return undefined;
+
+ // Step 3. Set url’s username to the empty string.
+ parsedUrl.username = '';
+
+ // Step 4. Set url’s password to null.
+ parsedUrl.password = '';
+
+ // Step 5. Set url’s fragment to null.
+ parsedUrl.hash = '';
+
+ // Step 6. If the origin-only flag is true, then:
+ if (originOnly) {
+ // Step 6.1. Set url’s path to null.
+ parsedUrl.pathname = '';
+ // Step 6.2. Set url’s query to null.
+ parsedUrl.search = '';
+ }
+ return parsedUrl.href;
+}
+
+function invokeScenario(scenario) {
+ const urls = getRequestURLs(
+ scenario.subresource,
+ scenario.origin,
+ scenario.redirection);
+ /** @type {Subresource} */
+ const subresource = {
+ subresourceType: scenario.subresource,
+ url: urls.testUrl,
+ policyDeliveries: scenario.subresource_policy_deliveries,
+ };
+
+ return invokeRequest(subresource, scenario.source_context_list);
+}
+
+const referrerUrlResolver = {
+ // The spec allows UAs to "enforce arbitrary policy considerations in the
+ // interests of minimizing data leakage"; to start to vaguely approximate
+ // this, we allow stronger policies to be used instead of what's specificed.
+ "omitted": function(sourceUrl) {
+ return [undefined];
+ },
+ "origin": function(sourceUrl) {
+ return [stripUrlForUseAsReferrer(sourceUrl, true),
+ undefined];
+ },
+ "stripped-referrer": function(sourceUrl) {
+ return [stripUrlForUseAsReferrer(sourceUrl, false),
+ stripUrlForUseAsReferrer(sourceUrl, true),
+ undefined];
+ }
+};
+
+function checkResult(scenario, expectation, result) {
+// https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer
+ let referrerSource = result.sourceContextUrl;
+ const sentFromSrcdoc = scenario.source_context_list.length > 0 &&
+ scenario.source_context_list[scenario.source_context_list.length - 1]
+ .sourceContextType === 'srcdoc';
+ if (sentFromSrcdoc) {
+ // Step 3. While document is an iframe srcdoc document, let document be
+ // document's browsing context's browsing context container's node
+ // document. [spec text]
+
+ // Workaround for srcdoc cases. Currently we only test <iframe srcdoc>
+ // inside the top-level Document, so |document| in the spec here is
+ // the top-level Document.
+ // This doesn't work if e.g. we test <iframe srcdoc> inside another
+ // external <iframe>.
+ referrerSource = location.toString();
+ }
+ const possibleReferrerUrls =
+ referrerUrlResolver[expectation](referrerSource);
+
+ // Check the reported URL.
+ assert_in_array(result.referrer,
+ possibleReferrerUrls,
+ "document.referrer");
+ assert_in_array(result.headers.referer,
+ possibleReferrerUrls,
+ "HTTP Referer header");
+}
+
+function runLengthTest(scenario, urlLength, expectation, testDescription) {
+ // `Referer` headers with length over 4k are culled down to an origin, so,
+ // let's test around that boundary for tests that would otherwise return
+ // the complete URL.
+ history.pushState(null, null, "/");
+ history.replaceState(null, null,
+ "A".repeat(urlLength - location.href.length));
+
+ promise_test(t => {
+ assert_equals(scenario.expectation, "stripped-referrer");
+ // Only on top-level Window, due to navigations using `history`.
+ assert_equals(scenario.source_context_list.length, 0);
+
+ return invokeScenario(scenario)
+ .then(result => checkResult(scenario, expectation, result));
+ }, testDescription);
+}
+
+function TestCase(scenarios, sanityChecker) {
+ function runTest(scenario) {
+ // This check is A NOOP in release.
+ sanityChecker.checkScenario(scenario);
+
+ promise_test(_ => {
+ return invokeScenario(scenario)
+ .then(result => checkResult(scenario, scenario.expectation, result));
+ }, scenario.test_description);
+ }
+
+ function runTests() {
+ for (const scenario of scenarios) {
+ runTest(scenario);
+ }
+ }
+
+ return {start: runTests};
+}
diff --git a/testing/web-platform/tests/referrer-policy/generic/unsupported-csp-referrer-directive.html b/testing/web-platform/tests/referrer-policy/generic/unsupported-csp-referrer-directive.html
new file mode 100644
index 0000000000..27a3a99113
--- /dev/null
+++ b/testing/web-platform/tests/referrer-policy/generic/unsupported-csp-referrer-directive.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Referrer Policy: CSP 'referrer' directive should not be supported</title>
+ <meta http-equiv="Content-Security-Policy" content="referrer no-referrer">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- Common global functions for referrer-policy tests. -->
+ <script src="/common/security-features/resources/common.sub.js"></script>
+ </head>
+ <body>
+ <h1>Referrer Policy: CSP 'referrer' directive should not be supported</h1>
+ <p>CSP used to have a 'referrer' directive to set a Referrer Policy. This directive has been removed and should not be supported.</p>
+
+ <pre id="received_message">Running...</pre>
+
+ <script>
+ promise_test(function() {
+ var urlPath = '/common/security-features/subresource/image.py?cache_destroyer=' + (new Date()).getTime();
+ return requestViaImage(urlPath, null, 'always')
+ .then(function(message) {
+ assert_equals(message.referrer, document.location.href);
+ });
+ }, "Image has a referrer despite CSP 'referrer' directive");
+ </script>
+
+ <div id="log"></div>
+ </body>
+</html>