Restrict Referer to just the origin for third parties in private mode and third parti...
authorwilander@apple.com <wilander@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Feb 2018 20:09:51 +0000 (20:09 +0000)
committerwilander@apple.com <wilander@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Feb 2018 20:09:51 +0000 (20:09 +0000)
https://bugs.webkit.org/show_bug.cgi?id=182559
<rdar://problem/36990337>

Reviewed by Andy Estes.

Source/WebCore:

Tests: http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-redirects.html
       http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-requests.html
       http/tests/security/strip-referrer-to-origin-for-third-party-redirects-in-private-mode.html
       http/tests/security/strip-referrer-to-origin-for-third-party-requests-in-private-mode.html

* page/SecurityPolicy.cpp:
(WebCore::SecurityPolicy::referrerToOriginString):
    Now exposed within WebCore. This is to make sure we create a proper referrer
    string in WebCore::ResourceRequestBase::setExistingHTTPReferrerToOriginString().
(WebCore::referrerToOriginString): Deleted.
    Used to be internal.
* page/SecurityPolicy.h:
* platform/network/ResourceRequestBase.cpp:
(WebCore::ResourceRequestBase::setExistingHTTPReferrerToOriginString):
    New, exported function used in WebKit. Note that this function does not
    set the referrer if the request has none since before.
* platform/network/ResourceRequestBase.h:

Source/WebKit:

* NetworkProcess/cocoa/NetworkDataTaskCocoa.h:
* NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
(WebKit::NetworkDataTaskCocoa::isThirdPartyRequest):
    New convenience function. Checks whether the resource shares
    partition with the first party.
(WebKit::NetworkDataTaskCocoa::NetworkDataTaskCocoa):
    Now strips the referrer to just the origin for:
    1. All third party requests in private mode.
    2. Third party requests to domains that ITP blocks cookies for.
(WebKit::NetworkDataTaskCocoa::willPerformHTTPRedirection):
    Now strips the referrer in redirects to just the origin for:
    1. All third party requests in private mode.
    2. Third party requests to domains that ITP blocks cookies for.

LayoutTests:

* TestExpectations:
    New tests marked as [ Skip ]. The change only applies to iOS and Mac.
* http/tests/resourceLoadStatistics/resources/echo-referrer.php: Added.
* http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-redirects-expected.txt: Added.
* http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-redirects.html: Added.
* http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-requests-expected.txt: Added.
* http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-requests.html: Added.
* http/tests/security/resources/echo-referrer.php: Added.
* http/tests/security/resources/redirect.php: Added.
* http/tests/security/strip-referrer-to-origin-for-third-party-redirects-in-private-mode-expected.txt: Added.
* http/tests/security/strip-referrer-to-origin-for-third-party-redirects-in-private-mode.html: Added.
* http/tests/security/strip-referrer-to-origin-for-third-party-requests-in-private-mode-expected.txt: Added.
* http/tests/security/strip-referrer-to-origin-for-third-party-requests-in-private-mode.html: Added.
* platform/ios/TestExpectations:
    New tests marked as [ Pass ].
* platform/mac-wk2/TestExpectations:
    New tests marked as [ Pass ].
* platform/wk2/TestExpectations:
    New tests marked as [ Skip ].

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@228239 268f45cc-cd09-0410-ab3c-d52691b4dbfc

24 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/http/tests/resourceLoadStatistics/resources/echo-referrer.php [new file with mode: 0644]
LayoutTests/http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-redirects-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-redirects.html [new file with mode: 0644]
LayoutTests/http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-requests-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-requests.html [new file with mode: 0644]
LayoutTests/http/tests/security/resources/echo-referrer.php [new file with mode: 0644]
LayoutTests/http/tests/security/resources/redirect.php [new file with mode: 0644]
LayoutTests/http/tests/security/strip-referrer-to-origin-for-third-party-redirects-in-private-mode-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/strip-referrer-to-origin-for-third-party-redirects-in-private-mode.html [new file with mode: 0644]
LayoutTests/http/tests/security/strip-referrer-to-origin-for-third-party-requests-in-private-mode-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/strip-referrer-to-origin-for-third-party-requests-in-private-mode.html [new file with mode: 0644]
LayoutTests/platform/ios/TestExpectations
LayoutTests/platform/mac-wk2/TestExpectations
LayoutTests/platform/wk2/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/page/SecurityPolicy.cpp
Source/WebCore/page/SecurityPolicy.h
Source/WebCore/platform/network/ResourceRequestBase.cpp
Source/WebCore/platform/network/ResourceRequestBase.h
Source/WebKit/ChangeLog
Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.h
Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm

index 246a7bb..4a983d4 100644 (file)
@@ -1,3 +1,31 @@
+2018-02-07  John Wilander  <wilander@apple.com>
+
+        Restrict Referer to just the origin for third parties in private mode and third parties ITP blocks cookies for in regular mode
+        https://bugs.webkit.org/show_bug.cgi?id=182559
+        <rdar://problem/36990337>
+
+        Reviewed by Andy Estes.
+
+        * TestExpectations:
+            New tests marked as [ Skip ]. The change only applies to iOS and Mac.
+        * http/tests/resourceLoadStatistics/resources/echo-referrer.php: Added.
+        * http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-redirects-expected.txt: Added.
+        * http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-redirects.html: Added.
+        * http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-requests-expected.txt: Added.
+        * http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-requests.html: Added.
+        * http/tests/security/resources/echo-referrer.php: Added.
+        * http/tests/security/resources/redirect.php: Added.
+        * http/tests/security/strip-referrer-to-origin-for-third-party-redirects-in-private-mode-expected.txt: Added.
+        * http/tests/security/strip-referrer-to-origin-for-third-party-redirects-in-private-mode.html: Added.
+        * http/tests/security/strip-referrer-to-origin-for-third-party-requests-in-private-mode-expected.txt: Added.
+        * http/tests/security/strip-referrer-to-origin-for-third-party-requests-in-private-mode.html: Added.
+        * platform/ios/TestExpectations:
+            New tests marked as [ Pass ].
+        * platform/mac-wk2/TestExpectations:
+            New tests marked as [ Pass ].
+        * platform/wk2/TestExpectations:
+            New tests marked as [ Skip ].
+
 2018-02-07  Matt Lewis  <jlewis3@apple.com>
 
         Adjusted test expectations for storage/indexeddb/modern/idbtransaction-objectstore-failures.html.
index 7c3d92f..14a3ac4 100644 (file)
@@ -128,6 +128,8 @@ fast/media/mq-inverted-colors-live-update-in-subframes.html [ Skip ]
 fast/media/mq-monochrome-live-update.html [ Skip ]
 fast/media/mq-prefers-reduced-motion-live-update.html [ Skip ]
 http/tests/loading/basic-auth-remove-credentials.html [ Skip ]
+http/tests/security/strip-referrer-to-origin-for-third-party-redirects-in-private-mode.html [ Skip ]
+http/tests/security/strip-referrer-to-origin-for-third-party-requests-in-private-mode.html [ Skip ]
 
 # ApplePay is only available on iOS (greater than iOS 10) and macOS (greater than macOS 10.12) and only for WebKit2.
 http/tests/ssl/applepay/ [ Skip ]
diff --git a/LayoutTests/http/tests/resourceLoadStatistics/resources/echo-referrer.php b/LayoutTests/http/tests/resourceLoadStatistics/resources/echo-referrer.php
new file mode 100644 (file)
index 0000000..045584b
--- /dev/null
@@ -0,0 +1,4 @@
+<?php
+header("Access-Control-Allow-Origin: http://127.0.0.1:8000");
+echo $_SERVER['HTTP_REFERER'];
+?>
\ No newline at end of file
diff --git a/LayoutTests/http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-redirects-expected.txt b/LayoutTests/http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-redirects-expected.txt
new file mode 100644 (file)
index 0000000..e4d588d
--- /dev/null
@@ -0,0 +1,15 @@
+Tests that only the origin is sent as referrer in redirects to prevalent resources without user interaction.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS referrer is "http://127.0.0.1:8000/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-redirects.html"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+http://127.0.0.1:8000/
diff --git a/LayoutTests/http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-redirects.html b/LayoutTests/http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-redirects.html
new file mode 100644 (file)
index 0000000..9d35a91
--- /dev/null
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src="/js-test-resources/js-test.js"></script>
+</head>
+<body>
+<script>
+    description("Tests that only the origin is sent as referrer in redirects to prevalent resources without user interaction.");
+    jsTestIsAsync = true;
+    testRunner.dumpChildFramesAsText();
+
+    function setEnableFeature(enable) {
+        if (!enable)
+            testRunner.statisticsResetToConsistentState();
+        internals.setResourceLoadStatisticsEnabled(enable);
+        testRunner.setCookieStoragePartitioningEnabled(enable);
+    }
+
+    function openIframe(url, onLoadHandler) {
+        const element = document.createElement("iframe");
+        element.src = url;
+        if (onLoadHandler) {
+            element.onload = onLoadHandler;
+        }
+        document.body.appendChild(element);
+    }
+
+    setEnableFeature(true);
+    if (testRunner.isStatisticsPrevalentResource("http://localhost"))
+        testFailed("Localhost was classified as prevalent resource before the test started.");
+
+    var referrer;
+    fetch("resources/echo-referrer.php").then(function(response) {
+        return response.text();
+    }).then(function(data) {
+        referrer = data;
+        shouldBeEqualToString("referrer", "http://127.0.0.1:8000/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-redirects.html");
+
+        testRunner.setStatisticsPrevalentResource("http://localhost", true);
+        if (!testRunner.isStatisticsPrevalentResource("http://localhost"))
+            testFailed("Host did not get set as prevalent resource.");
+
+        testRunner.statisticsUpdateCookiePartitioning(function() {
+            openIframe("resources/redirect.php?redirectTo=http://localhost:8000/resourceLoadStatistics/resources/echo-referrer.php", finishJSTest);
+        });
+
+    }).catch(function(error) {
+        console.log(error.message);
+        finishJSTest();
+    });
+
+</script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-requests-expected.txt b/LayoutTests/http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-requests-expected.txt
new file mode 100644 (file)
index 0000000..ab1ac49
--- /dev/null
@@ -0,0 +1,16 @@
+Tests that only the origin is sent as referrer for prevalent resources without user interaction.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS referrer is "http://127.0.0.1:8000/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-requests.html"
+PASS referrer is "http://127.0.0.1:8000/"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+http://127.0.0.1:8000/
diff --git a/LayoutTests/http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-requests.html b/LayoutTests/http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-requests.html
new file mode 100644 (file)
index 0000000..aa0b088
--- /dev/null
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src="/js-test-resources/js-test.js"></script>
+</head>
+<body>
+<script>
+    description("Tests that only the origin is sent as referrer for prevalent resources without user interaction.");
+    jsTestIsAsync = true;
+    testRunner.dumpChildFramesAsText();
+
+    function setEnableFeature(enable) {
+        if (!enable)
+            testRunner.statisticsResetToConsistentState();
+        internals.setResourceLoadStatisticsEnabled(enable);
+        testRunner.setCookieStoragePartitioningEnabled(enable);
+    }
+
+    function openIframe(url, onLoadHandler) {
+        const element = document.createElement("iframe");
+        element.src = url;
+        if (onLoadHandler) {
+            element.onload = onLoadHandler;
+        }
+        document.body.appendChild(element);
+    }
+
+    setEnableFeature(true);
+    if (testRunner.isStatisticsPrevalentResource("http://localhost"))
+        testFailed("Localhost was classified as prevalent resource before the test started.");
+
+    var referrer;
+    fetch("resources/echo-referrer.php").then(function(response) {
+        return response.text();
+    }).then(function(data) {
+        referrer = data;
+        shouldBeEqualToString("referrer", "http://127.0.0.1:8000/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-requests.html");
+
+        testRunner.setStatisticsPrevalentResource("http://localhost", true);
+        if (!testRunner.isStatisticsPrevalentResource("http://localhost"))
+            testFailed("Host did not get set as prevalent resource.");
+
+        testRunner.statisticsUpdateCookiePartitioning(function() {
+            fetch("http://localhost:8000/resourceLoadStatistics/resources/echo-referrer.php").then(function(response) {
+                return response.text();
+            }).then(function(data) {
+                referrer = data;
+                shouldBeEqualToString("referrer", "http://127.0.0.1:8000/");
+
+                openIframe("resources/redirect.php?redirectTo=http://localhost:8000/resourceLoadStatistics/resources/echo-referrer.php", finishJSTest);
+
+            }).catch(function(error) {
+                console.log(error.message);
+                finishJSTest();
+            });
+        });
+
+    }).catch(function(error) {
+        console.log(error.message);
+        finishJSTest();
+    });
+
+</script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/resources/echo-referrer.php b/LayoutTests/http/tests/security/resources/echo-referrer.php
new file mode 100644 (file)
index 0000000..045584b
--- /dev/null
@@ -0,0 +1,4 @@
+<?php
+header("Access-Control-Allow-Origin: http://127.0.0.1:8000");
+echo $_SERVER['HTTP_REFERER'];
+?>
\ No newline at end of file
diff --git a/LayoutTests/http/tests/security/resources/redirect.php b/LayoutTests/http/tests/security/resources/redirect.php
new file mode 100644 (file)
index 0000000..646cb4b
--- /dev/null
@@ -0,0 +1,14 @@
+<?php
+$redirectURL = $_GET["redirectTo"];
+if (isset($_GET["name2"])) {
+    $redirectURL = $redirectURL . "&name2=" . $_GET["name2"];
+}
+if (isset($_GET["name3"])) {
+    $redirectURL = $redirectURL . "&name3=" . $_GET["name3"];
+}
+if (isset($_GET["message"])) {
+    $redirectURL = $redirectURL . "&message=" . $_GET["message"];
+}
+header('Location: ' . $redirectURL);
+die();
+?>
diff --git a/LayoutTests/http/tests/security/strip-referrer-to-origin-for-third-party-redirects-in-private-mode-expected.txt b/LayoutTests/http/tests/security/strip-referrer-to-origin-for-third-party-redirects-in-private-mode-expected.txt
new file mode 100644 (file)
index 0000000..a4b6749
--- /dev/null
@@ -0,0 +1,15 @@
+Tests that only the origin is sent as referrer for third-party redirects in private browsing mode.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS referrer is "http://127.0.0.1:8000/security/strip-referrer-to-origin-for-third-party-redirects-in-private-mode.html"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+http://127.0.0.1:8000/
diff --git a/LayoutTests/http/tests/security/strip-referrer-to-origin-for-third-party-redirects-in-private-mode.html b/LayoutTests/http/tests/security/strip-referrer-to-origin-for-third-party-redirects-in-private-mode.html
new file mode 100644 (file)
index 0000000..b26b8ad
--- /dev/null
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src="/js-test-resources/js-test.js"></script>
+</head>
+<body>
+<script>
+    description("Tests that only the origin is sent as referrer for third-party redirects in private browsing mode.");
+    jsTestIsAsync = true;
+
+    testRunner.setPrivateBrowsingEnabled(true);
+    testRunner.dumpChildFramesAsText();
+
+    function openIframe(url, onLoadHandler) {
+        const element = document.createElement("iframe");
+        element.src = url;
+        if (onLoadHandler) {
+            element.onload = onLoadHandler;
+        }
+        document.body.appendChild(element);
+    }
+
+    var referrer;
+    fetch("resources/echo-referrer.php").then(function(response) {
+        return response.text();
+    }).then(function(data) {
+        referrer = data;
+        shouldBeEqualToString("referrer", "http://127.0.0.1:8000/security/strip-referrer-to-origin-for-third-party-redirects-in-private-mode.html");
+
+        openIframe("resources/redirect.php?redirectTo=http://localhost:8000/security/resources/echo-referrer.php", finishJSTest);
+
+    }).catch(function(error) {
+        console.log(error.message);
+        finishJSTest();
+    });
+
+</script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/strip-referrer-to-origin-for-third-party-requests-in-private-mode-expected.txt b/LayoutTests/http/tests/security/strip-referrer-to-origin-for-third-party-requests-in-private-mode-expected.txt
new file mode 100644 (file)
index 0000000..d3b6489
--- /dev/null
@@ -0,0 +1,16 @@
+Tests that only the origin is sent as referrer for third-party resources in private browsing mode.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS referrer is "http://127.0.0.1:8000/security/strip-referrer-to-origin-for-third-party-requests-in-private-mode.html"
+PASS referrer is "http://127.0.0.1:8000/"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+http://127.0.0.1:8000/
diff --git a/LayoutTests/http/tests/security/strip-referrer-to-origin-for-third-party-requests-in-private-mode.html b/LayoutTests/http/tests/security/strip-referrer-to-origin-for-third-party-requests-in-private-mode.html
new file mode 100644 (file)
index 0000000..283e0c7
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src="/js-test-resources/js-test.js"></script>
+</head>
+<body>
+<script>
+    description("Tests that only the origin is sent as referrer for third-party resources in private browsing mode.");
+    jsTestIsAsync = true;
+
+    testRunner.setPrivateBrowsingEnabled(true);
+    testRunner.dumpChildFramesAsText();
+
+    function openIframe(url, onLoadHandler) {
+        const element = document.createElement("iframe");
+        element.src = url;
+        if (onLoadHandler) {
+            element.onload = onLoadHandler;
+        }
+        document.body.appendChild(element);
+    }
+
+    var referrer;
+    fetch("resources/echo-referrer.php").then(function(response) {
+        return response.text();
+    }).then(function(data) {
+        referrer = data;
+        shouldBeEqualToString("referrer", "http://127.0.0.1:8000/security/strip-referrer-to-origin-for-third-party-requests-in-private-mode.html");
+
+        fetch("http://localhost:8000/security/resources/echo-referrer.php").then(function(response) {
+            return response.text();
+        }).then(function(data) {
+            referrer = data;
+            shouldBeEqualToString("referrer", "http://127.0.0.1:8000/");
+            openIframe("http://localhost:8000/security/resources/echo-referrer.php", finishJSTest);
+        }).catch(function(error) {
+            console.log(error.message);
+            finishJSTest();
+        });
+
+    }).catch(function(error) {
+        console.log(error.message);
+        finishJSTest();
+    });
+
+</script>
+</body>
+</html>
index cd24d7e..ef68be4 100644 (file)
@@ -3020,6 +3020,12 @@ http/tests/resourceLoadStatistics/remove-blocking-in-redirect.html [ Pass ]
 http/tests/resourceLoadStatistics/grandfathering.html [ Pass ]
 http/tests/resourceLoadStatistics/clear-in-memory-and-persistent-store.html [ Pass ]
 http/tests/resourceLoadStatistics/clear-in-memory-and-persistent-store-one-hour.html [ Pass ]
+http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-redirects.html [ Pass ]
+http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-requests.html [ Pass ]
+
+# Skipped in general expectations since they only work on iOS and Mac, WK2.
+http/tests/security/strip-referrer-to-origin-for-third-party-redirects-in-private-mode.html [ Pass ]
+http/tests/security/strip-referrer-to-origin-for-third-party-requests-in-private-mode.html [ Pass ]
 
 webkit.org/b/175273 imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name.html [ Failure ]
 
index cf228b4..ae23a14 100644 (file)
@@ -810,6 +810,12 @@ webkit.org/b/176122 media/video-controls-drop-and-restore-timeline.html [ Pass F
 [ HighSierra+ ] http/tests/resourceLoadStatistics/clear-in-memory-and-persistent-store.html [ Pass ]
 [ HighSierra+ ] http/tests/resourceLoadStatistics/clear-in-memory-and-persistent-store-one-hour.html [ Pass ]
 [ HighSierra+ ] http/tests/resourceLoadStatistics/grandfathering.html [ Pass ]
+[ HighSierra+ ] http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-redirects.html [ Pass ]
+[ HighSierra+ ] http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-requests.html [ Pass ]
+
+# Skipped in general expectations since they only work on iOS and Mac, WK2.
+http/tests/security/strip-referrer-to-origin-for-third-party-redirects-in-private-mode.html [ Pass ]
+http/tests/security/strip-referrer-to-origin-for-third-party-requests-in-private-mode.html [ Pass ]
 
 # <rdar://problem/33555759>
 webkit.org/b/177616 [ HighSierra+ ] http/tests/media/video-buffered-range-contains-currentTime.html [ Pass Timeout ]
index b96d5c1..0dc9637 100644 (file)
@@ -705,6 +705,8 @@ http/tests/resourceLoadStatistics/add-partitioning-to-redirect.html [ Skip ]
 http/tests/resourceLoadStatistics/add-blocking-to-redirect.html [ Skip ]
 http/tests/resourceLoadStatistics/remove-partitioning-in-redirect.html [ Skip ]
 http/tests/resourceLoadStatistics/remove-blocking-in-redirect.html [ Skip ]
+http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-redirects.html [ Skip ]
+http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-requests.html [ Skip ]
 
 ### END OF (5) Progressions, expected successes that are expected failures in WebKit1.
 ########################################
index 91c58d5..24fb3d5 100644 (file)
@@ -1,3 +1,30 @@
+2018-02-07  John Wilander  <wilander@apple.com>
+
+        Restrict Referer to just the origin for third parties in private mode and third parties ITP blocks cookies for in regular mode
+        https://bugs.webkit.org/show_bug.cgi?id=182559
+        <rdar://problem/36990337>
+
+        Reviewed by Andy Estes.
+
+        Tests: http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-redirects.html
+               http/tests/resourceLoadStatistics/strip-referrer-to-origin-for-prevalent-subresource-requests.html
+               http/tests/security/strip-referrer-to-origin-for-third-party-redirects-in-private-mode.html
+               http/tests/security/strip-referrer-to-origin-for-third-party-requests-in-private-mode.html
+
+        * page/SecurityPolicy.cpp:
+        (WebCore::SecurityPolicy::referrerToOriginString):
+            Now exposed within WebCore. This is to make sure we create a proper referrer
+            string in WebCore::ResourceRequestBase::setExistingHTTPReferrerToOriginString().
+        (WebCore::referrerToOriginString): Deleted.
+            Used to be internal.
+        * page/SecurityPolicy.h:
+        * platform/network/ResourceRequestBase.cpp:
+        (WebCore::ResourceRequestBase::setExistingHTTPReferrerToOriginString):
+            New, exported function used in WebKit. Note that this function does not
+            set the referrer if the request has none since before.
+        * platform/network/ResourceRequestBase.h:
+
+
 2018-02-07  Zalan Bujtas  <zalan@apple.com>
 
         [RenderTreeBuilder] Remove RenderElement::destroyLeftoverChildren.
index baba5d8..1aed004 100644 (file)
@@ -67,7 +67,7 @@ bool SecurityPolicy::shouldHideReferrer(const URL& url, const String& referrer)
     return !URLIsSecureURL;
 }
 
-static String referrerToOriginString(const String& referrer)
+String SecurityPolicy::referrerToOriginString(const String& referrer)
 {
     String originString = SecurityOrigin::createFromString(referrer)->toString();
     if (originString == "null")
index 4b02e98..cd1916c 100644 (file)
@@ -42,6 +42,10 @@ public:
     // If you intend to send a referrer header, you should use generateReferrerHeader instead.
     WEBCORE_EXPORT static bool shouldHideReferrer(const URL&, const String& referrer);
 
+    // Returns the referrer's security origin plus a / to make it a canonical URL
+    // and thus useable as referrer.
+    static String referrerToOriginString(const String& referrer);
+
     // Returns the referrer modified according to the referrer policy for a
     // navigation to a given URL. If the referrer returned is empty, the
     // referrer header should be omitted.
index 8ba66c8..bdf8d22 100644 (file)
@@ -29,6 +29,7 @@
 #include "HTTPHeaderNames.h"
 #include "PublicSuffix.h"
 #include "ResourceRequest.h"
+#include "SecurityPolicy.h"
 #include <wtf/PointerComparison.h>
 
 namespace WebCore {
@@ -324,6 +325,14 @@ void ResourceRequestBase::setHTTPReferrer(const String& httpReferrer)
     setHTTPHeaderField(HTTPHeaderName::Referer, httpReferrer);
 }
 
+void ResourceRequestBase::setExistingHTTPReferrerToOriginString()
+{
+    if (!hasHTTPReferrer())
+        return;
+
+    setHTTPHeaderField(HTTPHeaderName::Referer, SecurityPolicy::referrerToOriginString(httpReferrer()));
+}
+    
 void ResourceRequestBase::clearHTTPReferrer()
 {
     updateResourceRequest(); 
index 34065f2..d92aafb 100644 (file)
@@ -110,6 +110,7 @@ public:
     WEBCORE_EXPORT String httpReferrer() const;
     bool hasHTTPReferrer() const;
     WEBCORE_EXPORT void setHTTPReferrer(const String&);
+    WEBCORE_EXPORT void setExistingHTTPReferrerToOriginString();
     WEBCORE_EXPORT void clearHTTPReferrer();
 
     String httpOrigin() const;
index 87cd1ab..5463046 100644 (file)
@@ -1,3 +1,25 @@
+2018-02-07  John Wilander  <wilander@apple.com>
+
+        Restrict Referer to just the origin for third parties in private mode and third parties ITP blocks cookies for in regular mode
+        https://bugs.webkit.org/show_bug.cgi?id=182559
+        <rdar://problem/36990337>
+
+        Reviewed by Andy Estes.
+
+        * NetworkProcess/cocoa/NetworkDataTaskCocoa.h:
+        * NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
+        (WebKit::NetworkDataTaskCocoa::isThirdPartyRequest):
+            New convenience function. Checks whether the resource shares
+            partition with the first party.
+        (WebKit::NetworkDataTaskCocoa::NetworkDataTaskCocoa):
+            Now strips the referrer to just the origin for:
+            1. All third party requests in private mode.
+            2. Third party requests to domains that ITP blocks cookies for.
+        (WebKit::NetworkDataTaskCocoa::willPerformHTTPRedirection):
+            Now strips the referrer in redirects to just the origin for:
+            1. All third party requests in private mode.
+            2. Third party requests to domains that ITP blocks cookies for.
+
 2018-02-07  Daniel Bates  <dabates@apple.com>
 
         Log error when authentication challenge is blocked due to an insecure request
index 4d56d95..8a5045b 100644 (file)
@@ -82,6 +82,7 @@ private:
     void applyCookieBlockingPolicy(bool shouldBlock);
     void applyCookiePartitioningPolicy(const String& requiredStoragePartition, const String& currentStoragePartition);
 #endif
+    bool isThirdPartyRequest(const WebCore::ResourceRequest&);
 
     RefPtr<SandboxExtension> m_sandboxExtension;
     RetainPtr<NSURLSessionDataTask> m_task;
index c0ce2ff..62f288d 100644 (file)
@@ -141,6 +141,11 @@ void NetworkDataTaskCocoa::applyCookiePartitioningPolicy(const String& requiredS
 }
 #endif
 
+bool NetworkDataTaskCocoa::isThirdPartyRequest(const WebCore::ResourceRequest& request)
+{
+    return request.partitionName(request.url().host()) != request.partitionName(request.firstPartyForCookies().host());
+}
+
 NetworkDataTaskCocoa::NetworkDataTaskCocoa(NetworkSession& session, NetworkDataTaskClient& client, const WebCore::ResourceRequest& requestWithCredentials, uint64_t frameID, uint64_t pageID, WebCore::StoredCredentialsPolicy storedCredentialsPolicy, WebCore::ContentSniffingPolicy shouldContentSniff, WebCore::ContentEncodingSniffingPolicy shouldContentEncodingSniff, bool shouldClearReferrerOnHTTPSToHTTPRedirect, PreconnectOnly shouldPreconnectOnly)
     : NetworkDataTask(session, client, requestWithCredentials, storedCredentialsPolicy, shouldClearReferrerOnHTTPSToHTTPRedirect)
     , m_frameID(frameID)
@@ -171,7 +176,14 @@ NetworkDataTaskCocoa::NetworkDataTaskCocoa(NetworkSession& session, NetworkDataT
         applyBasicAuthorizationHeader(request, m_initialCredential);
     }
 #endif
-    
+
+    bool shouldBlockCookies = false;
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+    shouldBlockCookies = session.networkStorageSession().shouldBlockCookies(request);
+#endif
+    if (shouldBlockCookies || (m_session->sessionID().isEphemeral() && isThirdPartyRequest(request)))
+        request.setExistingHTTPReferrerToOriginString();
+
     NSURLRequest *nsRequest = request.nsURLRequest(WebCore::UpdateHTTPBody);
     applySniffingPoliciesAndBindRequestToInferfaceIfNeeded(nsRequest, shouldContentSniff == WebCore::SniffContent && !url.isLocalFile(), shouldContentEncodingSniff == WebCore::ContentEncodingSniffingPolicy::Sniff);
 
@@ -197,7 +209,7 @@ NetworkDataTaskCocoa::NetworkDataTaskCocoa(NetworkSession& session, NetworkDataT
     }
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
-    if (auto shouldBlockCookies = session.networkStorageSession().shouldBlockCookies(request)) {
+    if (shouldBlockCookies) {
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING) && !RELEASE_LOG_DISABLED
         if (NetworkProcess::singleton().shouldLogCookieInformation())
             RELEASE_LOG_IF(m_session->sessionID().isAlwaysOnLoggingAllowed(), Network, "%p - NetworkDataTaskCocoa::logCookieInformation: pageID = %llu, frameID = %llu, taskID = %lu: Blocking cookies for URL %s", this, pageID, frameID, (unsigned long)[m_task taskIdentifier], nsRequest.URL.absoluteString.UTF8String);
@@ -312,10 +324,18 @@ void NetworkDataTaskCocoa::willPerformHTTPRedirection(WebCore::ResourceResponse&
         }
 #endif
     }
-    
+
+    bool shouldBlockCookies = false;
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
-    auto shouldBlockCookies = m_session->networkStorageSession().shouldBlockCookies(request);
+    shouldBlockCookies = m_session->networkStorageSession().shouldBlockCookies(request);
     LOG(NetworkSession, "%llu %s cookies for redirect URL %s", [m_task taskIdentifier], (shouldBlockCookies ? "Blocking" : "Not blocking"), request.url().string().utf8().data());
+#endif
+
+    if (shouldBlockCookies || (m_session->sessionID().isEphemeral() && isThirdPartyRequest(request)))
+        request.setExistingHTTPReferrerToOriginString();
+
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+    // Always apply the policy since blocking may need to be turned on or off in a redirect.
     applyCookieBlockingPolicy(shouldBlockCookies);
 
     if (!shouldBlockCookies) {