Skip to content
Permalink
Browse files
Omit document.referrer for third-party requests while in ephemeral mode
https://bugs.webkit.org/show_bug.cgi?id=244518
<rdar://99578273>

For third-party requests, omit document.referrer when accessed from JavaScript bindings while in ephemeral mode.

Reviewed by Darin Adler.

* LayoutTests/http/tests/resourceLoadStatistics/omit-document-referrer-nested-third-party-iframe-ephemeral-expected.txt: Added.
* LayoutTests/http/tests/resourceLoadStatistics/omit-document-referrer-nested-third-party-iframe-ephemeral.html: Added.
* LayoutTests/http/tests/resourceLoadStatistics/omit-document-referrer-third-party-iframe-ephemeral-expected.txt: Added.
* LayoutTests/http/tests/resourceLoadStatistics/omit-document-referrer-third-party-iframe-ephemeral.html: Added.
* LayoutTests/http/tests/resourceLoadStatistics/omit-referrer-for-navigation-ephemeral-expected.txt: Added.
* LayoutTests/http/tests/resourceLoadStatistics/omit-referrer-for-navigation-ephemeral.html: Added.
* Source/WebCore/dom/Document+HTML.idl:
* Source/WebCore/dom/Document.cpp:
(WebCore::Document::referrerForBindings):
* Source/WebCore/dom/Document.h:

Canonical link: https://commits.webkit.org/255649@main
  • Loading branch information
charliewolfe authored and pascoej committed Oct 17, 2022
1 parent bd28077 commit 09d247d939321de347298e1d0147bf28e69f9e4d
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 1 deletion.
@@ -0,0 +1,10 @@
Tests that document.referrer is omitted in nested third-party iframes while in private browsing mode.

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS document.referrer is [empty]
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,37 @@
<!-- webkit-test-runner [ useEphemeralSession=true ] -->
<!DOCTYPE html>
<html>
<head>
<script src="/js-test-resources/js-test.js"></script>
<script src="resources/util.js"></script>
</head>
<body onload="runTest()">
<script>
description("Tests that document.referrer is omitted in nested third-party iframes while in private browsing mode.");
jsTestIsAsync = true;

function receiveMessage(event) {
if (event.origin === "http://localhost:8000") {
if (event.data.indexOf("PASS") === -1)
testFailed(event.data.replace("FAIL ", ""));
else
testPassed(event.data.replace("PASS ", ""));
} else
testFailed("Received a message from an unexpected origin: " + event.origin);
setEnableFeature(false, finishJSTest);
}

window.addEventListener("message", receiveMessage, false);

function runTest() {
if (testRunner) {
setEnableFeature(true, function() {
let iframeElement = document.createElement("iframe");
iframeElement.src = "http://127.0.0.1:8000/resourceLoadStatistics/resources/nest-iframe-report-document-referrer.html";
document.body.appendChild(iframeElement);
});
}
}
</script>
</body>
</html>
@@ -0,0 +1,10 @@
Tests that document.referrer is omitted in third-party iframes while in private browsing mode.

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS document.referrer is [empty]
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,37 @@
<!-- webkit-test-runner [ useEphemeralSession=true ] -->
<!DOCTYPE html>
<html>
<head>
<script src="/js-test-resources/js-test.js"></script>
<script src="resources/util.js"></script>
</head>
<body onload="runTest()">
<script>
description("Tests that document.referrer is omitted in third-party iframes while in private browsing mode.");
jsTestIsAsync = true;

function receiveMessage(event) {
if (event.origin === "http://localhost:8000") {
if (event.data.indexOf("PASS") === -1)
testFailed(event.data.replace("FAIL ", ""));
else
testPassed(event.data.replace("PASS ", ""));
} else
testFailed("Received a message from an unexpected origin: " + event.origin);
setEnableFeature(false, finishJSTest);
}

window.addEventListener("message", receiveMessage, false);

function runTest() {
if (testRunner) {
setEnableFeature(true, function() {
let iframeElement = document.createElement("iframe");
iframeElement.src = "http://localhost:8000/resourceLoadStatistics/resources/report-document-referrer.html";
document.body.appendChild(iframeElement);
});
}
}
</script>
</body>
</html>
@@ -0,0 +1,10 @@
Check that document.referrer is omitted after a cross-site navigation with link query while in private browsing mode.

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS The referrer is omitted.
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,43 @@
<!-- webkit-test-runner [ useEphemeralSession=true ] -->
<!DOCTYPE html>
<html>
<head>
<meta name="referrer" content="unsafe-url">
<script src="/js-test-resources/js-test.js"></script>
<script src="/cookies/resources/cookie-utilities.js"></script>
<script src="resources/util.js"></script>
</head>
<body onload="setTimeout('runTest()', 0)">
<script>
description("Check that document.referrer is omitted after a cross-site navigation with link query while in private browsing mode.");
jsTestIsAsync = true;

let numberOfTries = 0;
function testReferrer() {
if (!document.referrer) {
testPassed("The referrer is omitted.");
setEnableFeature(false, finishJSTest);
} else if (++numberOfTries <= 5)
setTimeout(testReferrer, 200);
else {
testFailed("The referrer is not omitted: " + document.referrer);
setEnableFeature(false, finishJSTest);
}
}

function navigateCrossOrigin() {
document.location.href = destinationOrigin + "/resourceLoadStatistics/omit-referrer-for-navigation-ephemeral.html";
}

const destinationOrigin = "http://localhost:8000";
const prevalentResourceOrigin = "http://127.0.0.1:8000";
function runTest() {
if (document.location.origin === prevalentResourceOrigin) {
navigateCrossOrigin();
} else {
testReferrer();
}
}
</script>
</body>
</html>
@@ -32,7 +32,7 @@ partial interface Document {
// resource metadata management
[PutForwards=href, LegacyUnforgeable] readonly attribute Location? location;
attribute USVString domain;
readonly attribute USVString referrer;
[ImplementedAs=referrerForBindings] readonly attribute USVString referrer;
attribute USVString cookie;
readonly attribute DOMString lastModified;
readonly attribute DocumentReadyState readyState;
@@ -5437,6 +5437,15 @@ String Document::referrer()
return String();
}

String Document::referrerForBindings()
{
if (auto* page = this->page(); page
&& page->usesEphemeralSession()
&& !RegistrableDomain { URL { frame()->loader().referrer() } }.matches(securityOrigin().data()))
return String();
return referrer();
}

String Document::domain() const
{
return securityOrigin().domain();
@@ -994,6 +994,7 @@ class Document
WEBCORE_EXPORT ExceptionOr<void> setCookie(const String&);

WEBCORE_EXPORT String referrer();
String referrerForBindings();

WEBCORE_EXPORT String domain() const;
ExceptionOr<void> setDomain(const String& newDomain);

0 comments on commit 09d247d

Please sign in to comment.