Deny third-party cookie creation for prevalent resources without interaction
authorbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 Sep 2017 17:30:50 +0000 (17:30 +0000)
committerbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 Sep 2017 17:30:50 +0000 (17:30 +0000)
https://bugs.webkit.org/show_bug.cgi?id=175232
<rdar://problem/33709386>

Reviewed by Alex Christensen.

Source/WebCore:

Prior to Intelligent Tracking Prevention, WebKit would deny the ability to create a third party cookie if the user's
settings prohibited it. Due to the internal mechanics of cookie partitioning, we now accept the third party cookie,
but destroy it at some arbitrary moment which is difficult for websites to work with.

This patch revises WebKit so that attempts to set third party cookies without user interaction fails immediately,
which is what sites are expecting from Safari.

Tests: http/tests/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction.html

* platform/network/NetworkStorageSession.h:
* platform/network/cf/NetworkStorageSessionCFNet.cpp:
(WebCore::NetworkStorageSession::shouldPartitionCookies const): Revise for new naming.
(WebCore::NetworkStorageSession::shouldAllowThirdPartyCookies const): Allow third party cookies when the
user interaction property applies.
(WebCore::NetworkStorageSession::shouldBlockCookies const): Deny cookies for origins that are not allowed by
user interaction, and that are not being partitioned.
(WebCore::NetworkStorageSession::setPrevalentDomainsWithAndWithoutInteraction): Revise for new naming, and
to track prevalent origins with and without user interaction.
(WebCore::NetworkStorageSession::setShouldPartitionCookiesForHosts): Renamed to setPrevalentDomainsWithAndWithoutInteraction.
(WebCore::NetworkStorageSession::removePrevalentDomains): New helper function for testing.

Source/WebKit:

Prior to Intelligent Tracking Prevention, WebKit would deny the ability to create a third party cookie if the user's
settings prohibited it. Due to the internal mechanics of cookie partitioning, we now accept the third party cookie,
but destroy it at some arbitrary moment which is difficult for websites to work with.

This patch revises WebKit so that attempts to set third party cookies without user interaction fails immediately,
which is what sites are expecting from Safari.

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::updatePrevalentDomainsWithAndWithoutInteraction):
(WebKit::NetworkProcess::updateCookiePartitioningForTopPrivatelyOwnedDomains): Renamed to updatePrevalentDomainsWithAndWithoutInteraction.
* NetworkProcess/NetworkProcess.h:
* NetworkProcess/NetworkProcess.messages.in: Renamed the UpdateCookiePartitioningForTopPrivatelyOwnedDomains message
to UpdatePrevalentDomainsWithAndWithoutInteraction.
* NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
(WebKit::NetworkDataTaskCocoa::NetworkDataTaskCocoa): Recognize cases where a network session should block cookies, and
use the stateless session so we fail immediately when attempting an invalid cookie set operation.
* UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
(WebKit::WKWebsiteDataStore::_resourceLoadStatisticsSetShouldPartitionCookies): Use new helper function to clear partitioning state.
* UIProcess/WebResourceLoadStatisticsStore.cpp:
(WebKit::WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore): Update for revised naming.
(WebKit::WebResourceLoadStatisticsStore::updateCookiePartitioning): Track domains with and without interaction so that we can recognize
domains that should be immediately blocked from setting cookies.
(WebKit::WebResourceLoadStatisticsStore::updateCookiePartitioningForDomains): Update for revised naming.
(WebKit::WebResourceLoadStatisticsStore::scheduleClearPartitioningStateForDomains): Added helper function for testing.
* UIProcess/WebResourceLoadStatisticsStore.h:
* UIProcess/WebsiteData/WebsiteDataStore.cpp:
(WebKit::WebsiteDataStore::updatePrevalentDomainsWithAndWithoutInteraction): Update for revised naming.
(WebKit::WebsiteDataStore::enableResourceLoadStatisticsAndSetTestingCallback): Ditto.
(WebKit::WebsiteDataStore::updateCookiePartitioningForTopPrivatelyOwnedDomains): Renamed to updatePrevalentDomainsWithAndWithoutInteraction.
* UIProcess/WebsiteData/WebsiteDataStore.h:

LayoutTests:

* http/tests/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction-expected.txt: Added.
* http/tests/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction.html: Added.
* platform/mac-highsierra-wk2/TestExpectations: Add new test expectation.

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

17 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction.html [new file with mode: 0644]
LayoutTests/platform/mac-highsierra-wk2/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/platform/network/NetworkStorageSession.h
Source/WebCore/platform/network/cf/NetworkStorageSessionCFNet.cpp
Source/WebKit/ChangeLog
Source/WebKit/NetworkProcess/NetworkProcess.cpp
Source/WebKit/NetworkProcess/NetworkProcess.h
Source/WebKit/NetworkProcess/NetworkProcess.messages.in
Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm
Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.cpp
Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.h
Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h

index 11dc73f..fd688b4 100644 (file)
@@ -1,3 +1,15 @@
+2017-09-06  Brent Fulgham  <bfulgham@apple.com>
+
+        Deny third-party cookie creation for prevalent resources without interaction
+        https://bugs.webkit.org/show_bug.cgi?id=175232
+        <rdar://problem/33709386>
+
+        Reviewed by Alex Christensen.
+
+        * http/tests/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction-expected.txt: Added.
+        * http/tests/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction.html: Added.
+        * platform/mac-highsierra-wk2/TestExpectations: Add new test expectation.
+
 2017-09-06  Per Arne Vollan  <pvollan@apple.com>
 
         Layout Test http/tests/preload/single_download_preload.html is flaky.
diff --git a/LayoutTests/http/tests/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction-expected.txt b/LayoutTests/http/tests/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction-expected.txt
new file mode 100644 (file)
index 0000000..ac417b7
--- /dev/null
@@ -0,0 +1,90 @@
+main frame - didStartProvisionalLoadForFrame
+main frame - didCommitLoadForFrame
+main frame - didReceiveTitle: Test for Partitioned Cookies With and Without User Interaction
+main frame - didChangeLocationWithinPageForFrame
+main frame - willPerformClientRedirectToURL: http://localhost:8000/loading/resourceLoadStatistics/resources/set-cookie.php?name=firstPartyCookie&value=value#http://127.0.0.1:8000/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction.html#step2 
+main frame - didFinishDocumentLoadForFrame
+main frame - didFinishLoadForFrame
+main frame - didStartProvisionalLoadForFrame
+main frame - didCancelClientRedirectForFrame
+main frame - didCommitLoadForFrame
+main frame - didFinishDocumentLoadForFrame
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+main frame - willPerformClientRedirectToURL: http://127.0.0.1:8000/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction.html#step2 
+main frame - didStartProvisionalLoadForFrame
+main frame - didCancelClientRedirectForFrame
+main frame - didCommitLoadForFrame
+main frame - didReceiveTitle: Test for Partitioned Cookies With and Without User Interaction
+main frame - didChangeLocationWithinPageForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+main frame - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+main frame - didHandleOnloadEventsForFrame
+main frame - didChangeLocationWithinPageForFrame
+frame "<!--framePath //<!--frame1-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame1-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame1-->-->" - didFinishDocumentLoadForFrame
+main frame - didChangeLocationWithinPageForFrame
+frame "<!--framePath //<!--frame2-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame1-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame1-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame2-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame2-->-->" - didFinishDocumentLoadForFrame
+main frame - didChangeLocationWithinPageForFrame
+frame "<!--framePath //<!--frame3-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame2-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame2-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame3-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame3-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame4-->-->" - didStartProvisionalLoadForFrame
+frame "<!--framePath //<!--frame3-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame3-->-->" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame4-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame4-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame4-->-->" - didHandleOnloadEventsForFrame
+frame "<!--framePath //<!--frame4-->-->" - didFinishLoadForFrame
+main frame - didFinishLoadForFrame
+PASS successfullyParsed is true
+
+TEST COMPLETE
+  
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+Setting third party cookie.
+
+
+--------
+Frame: '<!--framePath //<!--frame1-->-->'
+--------
+Should receive no cookies.
+Did not receive cookie named 'firstPartyCookie'.
+Did not receive cookie named 'thirdPartyCookie'.
+Client-side document.cookie: firstPartyCookie=value
+
+--------
+Frame: '<!--framePath //<!--frame2-->-->'
+--------
+Setting partitioned, third party cookie.
+
+
+--------
+Frame: '<!--framePath //<!--frame3-->-->'
+--------
+Should receive partitioned, third party cookie.
+Did not receive cookie named 'firstPartyCookie'.
+Received cookie named 'thirdPartyCookie'.
+Client-side document.cookie: thirdPartyCookie=value
+
+--------
+Frame: '<!--framePath //<!--frame4-->-->'
+--------
+After user interaction, should receive non-partitioned, first party cookie.
+Received cookie named 'firstPartyCookie'.
+Did not receive cookie named 'thirdPartyCookie'.
+Client-side document.cookie: firstPartyCookie=value
diff --git a/LayoutTests/http/tests/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction.html b/LayoutTests/http/tests/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction.html
new file mode 100644 (file)
index 0000000..6490c81
--- /dev/null
@@ -0,0 +1,95 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Test for Partitioned Cookies With and Without User Interaction</title>
+    <script src="/js-test-resources/js-test.js"></script>
+</head>
+<body>
+<script>
+    const partitionHost = "127.0.0.1:8000";
+    const thirdPartyHostname = "localhost";
+    const thirdPartyOrigin = "http://" + thirdPartyHostname + ":8000";
+    const thirdPartyBaseUrl = thirdPartyOrigin + "/loading/resourceLoadStatistics/resources";
+    const firstPartyCookieName = "firstPartyCookie";
+    const subPathToSetFirstPartyCookie = "/set-cookie.php?name=" + firstPartyCookieName + "&value=value";
+    const thirdPartyCookieName = "thirdPartyCookie";
+    const subPathToSetThirdPartyCookie = "/set-cookie.php?name=" + thirdPartyCookieName + "&value=value";
+    const fragmentWithReturnUrl = "http://127.0.0.1:8000/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction.html";
+    const subPathToGetCookies = "/get-cookies.php?name1=" + firstPartyCookieName + "&name2=" + thirdPartyCookieName;
+
+    function setEnableFeature(enable) {
+        if (!enable) {
+            testRunner.statisticsResetToConsistentState();
+        }
+        testRunner.setStatisticsNotifyPagesWhenDataRecordsWereScanned(enable);
+        internals.setResourceLoadStatisticsEnabled(enable);
+        testRunner.setCookieStoragePartitioningEnabled(enable);
+    }
+
+    function finishTest() {
+        setEnableFeature(false);
+        testRunner.notifyDone();
+    }
+
+    function openIframe(url, onLoadHandler) {
+        const element = document.createElement("iframe");
+        element.src = url;
+        if (onLoadHandler) {
+            element.onload = onLoadHandler;
+        }
+        document.body.appendChild(element);
+    }
+
+    function setUserInteractionAndContinue() {
+        testRunner.setStatisticsHasHadUserInteraction(thirdPartyOrigin, true);
+        if (!testRunner.isStatisticsHasHadUserInteraction(thirdPartyOrigin))
+            testFailed("Third party did not get logged for user interaction.");
+        runTest();
+    }
+
+    function runTest() {
+        switch (document.location.hash) {
+            case "#step1":
+                document.location.href = thirdPartyBaseUrl + subPathToSetFirstPartyCookie + "#" + fragmentWithReturnUrl + "#step2";
+                break;
+            case "#step2":
+                document.location.hash = "step3";
+                openIframe(thirdPartyBaseUrl + subPathToSetThirdPartyCookie + "&message=Setting third party cookie.", runTest);
+                break;
+            case "#step3":
+                document.location.hash = "step4";
+                openIframe(thirdPartyBaseUrl + subPathToGetCookies + "&message=Should receive no cookies.", runTest);
+                break;
+            case "#step4":
+                document.location.hash = "step5";
+                testRunner.statisticsSetShouldPartitionCookiesForHost(thirdPartyHostname, true);
+                openIframe(thirdPartyBaseUrl + subPathToSetThirdPartyCookie + "&message=Setting partitioned, third party cookie.", runTest);
+                break;
+            case "#step5":
+                document.location.hash = "step6";
+                openIframe(thirdPartyBaseUrl + subPathToGetCookies + "&message=Should receive partitioned, third party cookie.", setUserInteractionAndContinue);
+                break;
+            case "#step6":
+                openIframe(thirdPartyBaseUrl + subPathToGetCookies + "&message=After user interaction, should receive non-partitioned, first party cookie.", finishTest);
+                break;
+        }
+    }
+
+    if (document.location.host === partitionHost && document.location.hash == "" && window.testRunner && window.internals) {
+        setEnableFeature(true);
+
+        // Start test with third party as non-prevalent
+        testRunner.setStatisticsPrevalentResource(thirdPartyHostname, false);
+        testRunner.setStatisticsHasHadUserInteraction(thirdPartyOrigin, false);
+        testRunner.statisticsSetShouldPartitionCookiesForHost(thirdPartyHostname, false);
+
+        testRunner.waitUntilDone();
+        testRunner.dumpChildFramesAsText();
+        document.location.hash = "step1";
+    }
+
+    runTest();
+</script>
+</body>
+</html>
index 9acd773..976028d 100644 (file)
@@ -6,6 +6,7 @@ http/tests/loading/resourceLoadStatistics/partitioned-cookies-with-and-without-u
 http/tests/loading/resourceLoadStatistics/clear-in-memory-and-persistent-store-one-hour.html [ Pass ]
 http/tests/loading/resourceLoadStatistics/partitioned-and-unpartitioned-cookie-deletion.html [ Pass ]
 http/tests/loading/resourceLoadStatistics/partitioned-and-unpartitioned-cookie-with-partitioning-timeout.html [ Pass ]
+http/tests/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction.html [ Pass ]
 
 # <rdar://problem/33555759>
 http/tests/media/video-buffered-range-contains-currentTime.html [ Pass ImageOnlyFailure ]
index 23d99a4..00e370f 100644 (file)
@@ -1,3 +1,32 @@
+2017-09-06  Brent Fulgham  <bfulgham@apple.com>
+
+        Deny third-party cookie creation for prevalent resources without interaction
+        https://bugs.webkit.org/show_bug.cgi?id=175232
+        <rdar://problem/33709386>
+
+        Reviewed by Alex Christensen.
+
+        Prior to Intelligent Tracking Prevention, WebKit would deny the ability to create a third party cookie if the user's
+        settings prohibited it. Due to the internal mechanics of cookie partitioning, we now accept the third party cookie,
+        but destroy it at some arbitrary moment which is difficult for websites to work with.
+        
+        This patch revises WebKit so that attempts to set third party cookies without user interaction fails immediately,
+        which is what sites are expecting from Safari.
+
+        Tests: http/tests/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction.html
+
+        * platform/network/NetworkStorageSession.h:
+        * platform/network/cf/NetworkStorageSessionCFNet.cpp:
+        (WebCore::NetworkStorageSession::shouldPartitionCookies const): Revise for new naming.
+        (WebCore::NetworkStorageSession::shouldAllowThirdPartyCookies const): Allow third party cookies when the
+        user interaction property applies.
+        (WebCore::NetworkStorageSession::shouldBlockCookies const): Deny cookies for origins that are not allowed by
+        user interaction, and that are not being partitioned.
+        (WebCore::NetworkStorageSession::setPrevalentDomainsWithAndWithoutInteraction): Revise for new naming, and
+        to track prevalent origins with and without user interaction.
+        (WebCore::NetworkStorageSession::setShouldPartitionCookiesForHosts): Renamed to setPrevalentDomainsWithAndWithoutInteraction.
+        (WebCore::NetworkStorageSession::removePrevalentDomains): New helper function for testing.
+
 2017-09-06  Tomas Popela  <tpopela@redhat.com>
 
         Missing break in URLParser
index b87ee51..09efeb6 100644 (file)
@@ -90,8 +90,10 @@ public:
     WEBCORE_EXPORT static void setCookieStoragePartitioningEnabled(bool);
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
     WEBCORE_EXPORT String cookieStoragePartition(const ResourceRequest&) const;
+    WEBCORE_EXPORT bool shouldBlockCookies(const ResourceRequest&) const;
     String cookieStoragePartition(const URL& firstPartyForCookies, const URL& resource) const;
-    WEBCORE_EXPORT void setShouldPartitionCookiesForHosts(const Vector<String>& domainsToRemove, const Vector<String>& domainsToAdd, bool clearFirst);
+    WEBCORE_EXPORT void setPrevalentDomainsWithAndWithoutInteraction(const Vector<String>& domainsWithInteraction, const Vector<String>& domainsWithoutInteraction, bool clearFirst);
+    WEBCORE_EXPORT void removePrevalentDomains(const Vector<String>& domains);
 #endif
 #elif USE(SOUP)
     NetworkStorageSession(PAL::SessionID, std::unique_ptr<SoupNetworkSession>&&);
@@ -146,7 +148,9 @@ private:
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
     bool shouldPartitionCookies(const String& topPrivatelyControlledDomain) const;
-    HashSet<String> m_topPrivatelyControlledDomainsForCookiePartitioning;
+    bool shouldAllowThirdPartyCookies(const String& topPrivatelyControlledDomain) const;
+    HashSet<String> m_prevalentTopPrivatelyControlledDomainsWithoutInteraction;
+    HashSet<String> m_prevalentTopPrivatelyControlledDomainsWithInteraction;
 #endif
 
 #if PLATFORM(COCOA)
index 4c9fc3d..41ff60f 100644 (file)
@@ -205,21 +205,65 @@ bool NetworkStorageSession::shouldPartitionCookies(const String& topPrivatelyCon
     if (topPrivatelyControlledDomain.isEmpty())
         return false;
 
-    return m_topPrivatelyControlledDomainsForCookiePartitioning.contains(topPrivatelyControlledDomain);
+    return m_prevalentTopPrivatelyControlledDomainsWithoutInteraction.contains(topPrivatelyControlledDomain);
 }
 
-void NetworkStorageSession::setShouldPartitionCookiesForHosts(const Vector<String>& domainsToRemove, const Vector<String>& domainsToAdd, bool clearFirst)
+bool NetworkStorageSession::shouldAllowThirdPartyCookies(const String& topPrivatelyControlledDomain) const
 {
-    if (clearFirst)
-        m_topPrivatelyControlledDomainsForCookiePartitioning.clear();
+    if (topPrivatelyControlledDomain.isEmpty())
+        return false;
+
+    return m_prevalentTopPrivatelyControlledDomainsWithInteraction.contains(topPrivatelyControlledDomain);
+}
+
+bool NetworkStorageSession::shouldBlockCookies(const ResourceRequest& request) const
+{
+    if (!cookieStoragePartitioningEnabled)
+        return false;
+
+    auto firstPartyDomain = getPartitioningDomain(request.firstPartyForCookies());
+    if (firstPartyDomain.isEmpty())
+        return false;
+
+    auto resourceDomain = getPartitioningDomain(request.url());
+    if (resourceDomain.isEmpty())
+        return false;
+
+    if (firstPartyDomain == resourceDomain)
+        return false;
+
+    if (shouldPartitionCookies(resourceDomain))
+        return false;
+
+    return !shouldAllowThirdPartyCookies(resourceDomain);
+}
+
+void NetworkStorageSession::setPrevalentDomainsWithAndWithoutInteraction(const Vector<String>& domainsWithInteraction, const Vector<String>& domainsWithoutInteraction, bool clearFirst)
+{
+    if (clearFirst) {
+        m_prevalentTopPrivatelyControlledDomainsWithoutInteraction.clear();
+        m_prevalentTopPrivatelyControlledDomainsWithInteraction.clear();
+    }
+
+    for (auto& domain : domainsWithInteraction) {
+        if (!clearFirst)
+            m_prevalentTopPrivatelyControlledDomainsWithoutInteraction.remove(domain);
+        m_prevalentTopPrivatelyControlledDomainsWithInteraction.add(domain);
+    }
 
-    if (!domainsToRemove.isEmpty()) {
-        for (auto& domain : domainsToRemove)
-            m_topPrivatelyControlledDomainsForCookiePartitioning.remove(domain);
+    for (auto& domain : domainsWithoutInteraction) {
+        m_prevalentTopPrivatelyControlledDomainsWithoutInteraction.add(domain);
+        if (!clearFirst)
+            m_prevalentTopPrivatelyControlledDomainsWithInteraction.remove(domain);
+    }
+}
+
+void NetworkStorageSession::removePrevalentDomains(const Vector<String>& domains)
+{
+    for (auto& domain : domains) {
+        m_prevalentTopPrivatelyControlledDomainsWithoutInteraction.remove(domain);
+        m_prevalentTopPrivatelyControlledDomainsWithInteraction.remove(domain);
     }
-        
-    if (!domainsToAdd.isEmpty())
-        m_topPrivatelyControlledDomainsForCookiePartitioning.add(domainsToAdd.begin(), domainsToAdd.end());
 }
 
 #endif // HAVE(CFNETWORK_STORAGE_PARTITIONING)
index 0f60cde..364d8e5 100644 (file)
@@ -1,3 +1,42 @@
+2017-09-06  Brent Fulgham  <bfulgham@apple.com>
+
+        Deny third-party cookie creation for prevalent resources without interaction
+        https://bugs.webkit.org/show_bug.cgi?id=175232
+        <rdar://problem/33709386>
+
+        Reviewed by Alex Christensen.
+
+        Prior to Intelligent Tracking Prevention, WebKit would deny the ability to create a third party cookie if the user's
+        settings prohibited it. Due to the internal mechanics of cookie partitioning, we now accept the third party cookie,
+        but destroy it at some arbitrary moment which is difficult for websites to work with.
+        
+        This patch revises WebKit so that attempts to set third party cookies without user interaction fails immediately,
+        which is what sites are expecting from Safari.
+
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::updatePrevalentDomainsWithAndWithoutInteraction):
+        (WebKit::NetworkProcess::updateCookiePartitioningForTopPrivatelyOwnedDomains): Renamed to updatePrevalentDomainsWithAndWithoutInteraction.
+        * NetworkProcess/NetworkProcess.h:
+        * NetworkProcess/NetworkProcess.messages.in: Renamed the UpdateCookiePartitioningForTopPrivatelyOwnedDomains message
+        to UpdatePrevalentDomainsWithAndWithoutInteraction.
+        * NetworkProcess/cocoa/NetworkDataTaskCocoa.mm:
+        (WebKit::NetworkDataTaskCocoa::NetworkDataTaskCocoa): Recognize cases where a network session should block cookies, and
+        use the stateless session so we fail immediately when attempting an invalid cookie set operation.
+        * UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
+        (WebKit::WKWebsiteDataStore::_resourceLoadStatisticsSetShouldPartitionCookies): Use new helper function to clear partitioning state.
+        * UIProcess/WebResourceLoadStatisticsStore.cpp:
+        (WebKit::WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore): Update for revised naming.
+        (WebKit::WebResourceLoadStatisticsStore::updateCookiePartitioning): Track domains with and without interaction so that we can recognize
+        domains that should be immediately blocked from setting cookies.
+        (WebKit::WebResourceLoadStatisticsStore::updateCookiePartitioningForDomains): Update for revised naming.
+        (WebKit::WebResourceLoadStatisticsStore::scheduleClearPartitioningStateForDomains): Added helper function for testing.
+        * UIProcess/WebResourceLoadStatisticsStore.h:
+        * UIProcess/WebsiteData/WebsiteDataStore.cpp:
+        (WebKit::WebsiteDataStore::updatePrevalentDomainsWithAndWithoutInteraction): Update for revised naming.
+        (WebKit::WebsiteDataStore::enableResourceLoadStatisticsAndSetTestingCallback): Ditto.
+        (WebKit::WebsiteDataStore::updateCookiePartitioningForTopPrivatelyOwnedDomains): Renamed to updatePrevalentDomainsWithAndWithoutInteraction.
+        * UIProcess/WebsiteData/WebsiteDataStore.h:
+
 2017-09-06  Adrian Perez de Castro  <aperez@igalia.com>
 
         [WPE][CMake] Fix path to the WebKitApplicationInfo.h header.
index 5ae4eb8..fd7995a 100644 (file)
@@ -319,10 +319,16 @@ void NetworkProcess::didGrantSandboxExtensionsToStorageProcessForBlobs(uint64_t
 }
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
-void NetworkProcess::updateCookiePartitioningForTopPrivatelyOwnedDomains(PAL::SessionID sessionID, const Vector<String>& domainsToRemove, const Vector<String>& domainsToAdd,  bool shouldClearFirst)
+void NetworkProcess::updatePrevalentDomainsWithAndWithoutInteraction(PAL::SessionID sessionID, const Vector<String>& domainsWithInteraction, const Vector<String>& domainsWithoutInteraction, bool shouldClearFirst)
 {
     if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
-        networkStorageSession->setShouldPartitionCookiesForHosts(domainsToRemove, domainsToAdd, shouldClearFirst);
+        networkStorageSession->setPrevalentDomainsWithAndWithoutInteraction(domainsWithInteraction, domainsWithoutInteraction, shouldClearFirst);
+}
+
+void NetworkProcess::removePrevalentDomains(PAL::SessionID sessionID, const Vector<String>& domains)
+{
+    if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
+        networkStorageSession->removePrevalentDomains(domains);
 }
 #endif
 
index d15abb3..b8f7941 100644 (file)
@@ -130,7 +130,8 @@ public:
     void grantSandboxExtensionsToStorageProcessForBlobs(const Vector<String>& filenames, Function<void ()>&& completionHandler);
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
-    void updateCookiePartitioningForTopPrivatelyOwnedDomains(PAL::SessionID, const Vector<String>& domainsToRemove, const Vector<String>& domainsToAdd, bool shouldClearFirst);
+    void updatePrevalentDomainsWithAndWithoutInteraction(PAL::SessionID, const Vector<String>& domainsWithInteraction, const Vector<String>& domainsWithoutInteraction, bool shouldClearFirst);
+    void removePrevalentDomains(PAL::SessionID, const Vector<String>& domains);
 #endif
 
     Seconds loadThrottleLatency() const { return m_loadThrottleLatency; }
index 5ef1653..9854700 100644 (file)
@@ -83,6 +83,7 @@ messages -> NetworkProcess LegacyReceiver {
     DidGrantSandboxExtensionsToStorageProcessForBlobs(uint64_t requestID)
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
-    UpdateCookiePartitioningForTopPrivatelyOwnedDomains(PAL::SessionID sessionID, Vector<String> domainsToRemove, Vector<String> domainsToAdd, bool shouldClearFirst)
+    UpdatePrevalentDomainsWithAndWithoutInteraction(PAL::SessionID sessionID, Vector<String> domainsWithInteraction, Vector<String> domainsWithoutInteraction, bool shouldClearFirst)
+    RemovePrevalentDomains(PAL::SessionID sessionID, Vector<String> domainsWithInteraction);
 #endif
 }
index 152d78c..a48476e 100644 (file)
@@ -111,22 +111,30 @@ NetworkDataTaskCocoa::NetworkDataTaskCocoa(NetworkSession& session, NetworkDataT
     }
 
     auto& cocoaSession = static_cast<NetworkSessionCocoa&>(m_session.get());
+    if (session.networkStorageSession().shouldBlockCookies(request)) {
+        storedCredentials = WebCore::DoNotAllowStoredCredentials;
+        m_storedCredentials = WebCore::DoNotAllowStoredCredentials;
+    }
+
     if (storedCredentials == WebCore::AllowStoredCredentials) {
         m_task = [cocoaSession.m_sessionWithCredentialStorage dataTaskWithRequest:nsRequest];
         ASSERT(!cocoaSession.m_dataTaskMapWithCredentials.contains([m_task taskIdentifier]));
         cocoaSession.m_dataTaskMapWithCredentials.add([m_task taskIdentifier], this);
+        LOG(NetworkSession, "%llu Creating stateless NetworkDataTask with URL %s", [m_task taskIdentifier], nsRequest.URL.absoluteString.UTF8String);
     } else {
         m_task = [cocoaSession.m_statelessSession dataTaskWithRequest:nsRequest];
         ASSERT(!cocoaSession.m_dataTaskMapWithoutState.contains([m_task taskIdentifier]));
         cocoaSession.m_dataTaskMapWithoutState.add([m_task taskIdentifier], this);
+        LOG(NetworkSession, "%llu Creating NetworkDataTask with URL %s", [m_task taskIdentifier], nsRequest.URL.absoluteString.UTF8String);
     }
-    LOG(NetworkSession, "%llu Creating NetworkDataTask with URL %s", [m_task taskIdentifier], nsRequest.URL.absoluteString.UTF8String);
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
-    String storagePartition = session.networkStorageSession().cookieStoragePartition(request);
-    if (!storagePartition.isEmpty()) {
-        LOG(NetworkSession, "%llu Partitioning cookies for URL %s", [m_task taskIdentifier], nsRequest.URL.absoluteString.UTF8String);
-        m_task.get()._storagePartitionIdentifier = storagePartition;
+    if (storedCredentials == WebCore::AllowStoredCredentials) {
+        String storagePartition = session.networkStorageSession().cookieStoragePartition(request);
+        if (!storagePartition.isEmpty()) {
+            LOG(NetworkSession, "%llu Partitioning cookies for URL %s", [m_task taskIdentifier], nsRequest.URL.absoluteString.UTF8String);
+            m_task.get()._storagePartitionIdentifier = storagePartition;
+        }
     }
 #endif
 
index 3f1dd2f..b8c9002 100644 (file)
@@ -418,7 +418,7 @@ static Vector<WebKit::WebsiteDataRecord> toWebsiteDataRecords(NSArray *dataRecor
     if (value)
         store->scheduleCookiePartitioningUpdateForDomains({ }, { host }, WebKit::ShouldClearFirst::No);
     else
-        store->scheduleCookiePartitioningUpdateForDomains({ host }, { }, WebKit::ShouldClearFirst::No);
+        store->scheduleClearPartitioningStateForDomains({ host });
 }
 
 - (void)_resourceLoadStatisticsSubmitTelemetry
index cece12e..134a70c 100644 (file)
@@ -145,10 +145,11 @@ static Vector<OperatingDate> mergeOperatingDates(const Vector<OperatingDate>& ex
     return mergedDates;
 }
 
-WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore(const String& resourceLoadStatisticsDirectory, Function<void (const String&)>&& testingCallback, UpdateCookiePartitioningForDomainsHandler&& updateCookiePartitioningForDomainsHandler)
+WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore(const String& resourceLoadStatisticsDirectory, Function<void (const String&)>&& testingCallback, UpdatePrevalentDomainsWithAndWithoutInteractionHandler&& updatePrevalentDomainsWithAndWithoutInteractionHandler, RemovePrevalentDomainsHandler&& removeDomainsHandler)
     : m_statisticsQueue(WorkQueue::create("WebResourceLoadStatisticsStore Process Data Queue", WorkQueue::Type::Serial, WorkQueue::QOS::Utility))
     , m_persistentStorage(*this, resourceLoadStatisticsDirectory)
-    , m_updateCookiePartitioningForDomainsHandler(WTFMove(updateCookiePartitioningForDomainsHandler))
+    , m_updatePrevalentDomainsWithAndWithoutInteractionHandler(WTFMove(updatePrevalentDomainsWithAndWithoutInteractionHandler))
+    , m_removeDomainsHandler(WTFMove(removeDomainsHandler))
     , m_dailyTasksTimer(RunLoop::main(), this, &WebResourceLoadStatisticsStore::performDailyTasks)
     , m_statisticsTestingCallback(WTFMove(testingCallback))
 {
@@ -468,6 +469,15 @@ void WebResourceLoadStatisticsStore::scheduleCookiePartitioningUpdateForDomains(
     });
 }
 
+void WebResourceLoadStatisticsStore::scheduleClearPartitioningStateForDomains(const Vector<String>& domains)
+{
+    // Helper function used by testing system. Should only be called from the main thread.
+    ASSERT(RunLoop::isMain());
+    m_statisticsQueue->dispatch([this, protectedThis = makeRef(*this), domains = crossThreadCopy(domains)] {
+        clearPartitioningStateForDomains(domains);
+    });
+}
+
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
 void WebResourceLoadStatisticsStore::scheduleCookiePartitioningStateReset()
 {
@@ -645,48 +655,62 @@ void WebResourceLoadStatisticsStore::updateCookiePartitioning()
 {
     ASSERT(!RunLoop::isMain());
 
-    Vector<String> domainsToRemove;
-    Vector<String> domainsToAdd;
+    Vector<String> domainsWithoutInteraction;
+    Vector<String> domainsWithInteraction;
     for (auto& resourceStatistic : m_resourceStatisticsMap.values()) {
         bool shouldPartition = shouldPartitionCookies(resourceStatistic);
         if (resourceStatistic.isMarkedForCookiePartitioning && !shouldPartition) {
             resourceStatistic.isMarkedForCookiePartitioning = false;
-            domainsToRemove.append(resourceStatistic.highLevelDomain);
+            domainsWithInteraction.append(resourceStatistic.highLevelDomain);
         } else if (!resourceStatistic.isMarkedForCookiePartitioning && shouldPartition) {
             resourceStatistic.isMarkedForCookiePartitioning = true;
-            domainsToAdd.append(resourceStatistic.highLevelDomain);
+            domainsWithoutInteraction.append(resourceStatistic.highLevelDomain);
         }
     }
 
-    if (domainsToRemove.isEmpty() && domainsToAdd.isEmpty())
+    if (domainsWithInteraction.isEmpty() && domainsWithoutInteraction.isEmpty())
         return;
 
-    RunLoop::main().dispatch([this, protectedThis = makeRef(*this), domainsToRemove = crossThreadCopy(domainsToRemove), domainsToAdd = crossThreadCopy(domainsToAdd)] () {
-        m_updateCookiePartitioningForDomainsHandler(domainsToRemove, domainsToAdd, ShouldClearFirst::No);
+    RunLoop::main().dispatch([this, protectedThis = makeRef(*this), domainsWithInteraction = crossThreadCopy(domainsWithInteraction), domainsWithoutInteraction = crossThreadCopy(domainsWithoutInteraction)] () {
+        m_updatePrevalentDomainsWithAndWithoutInteractionHandler(domainsWithInteraction, domainsWithoutInteraction, ShouldClearFirst::No);
     });
 }
 
-void WebResourceLoadStatisticsStore::updateCookiePartitioningForDomains(const Vector<String>& domainsToRemove, const Vector<String>& domainsToAdd, ShouldClearFirst shouldClearFirst)
+void WebResourceLoadStatisticsStore::updateCookiePartitioningForDomains(const Vector<String>& domainsWithInteraction, const Vector<String>& domainsWithoutInteraction, ShouldClearFirst shouldClearFirst)
 {
     ASSERT(!RunLoop::isMain());
-    if (domainsToRemove.isEmpty() && domainsToAdd.isEmpty())
+    if (domainsWithInteraction.isEmpty() && domainsWithoutInteraction.isEmpty())
         return;
 
-    RunLoop::main().dispatch([this, shouldClearFirst, protectedThis = makeRef(*this), domainsToRemove = crossThreadCopy(domainsToRemove), domainsToAdd = crossThreadCopy(domainsToAdd)] () {
-        m_updateCookiePartitioningForDomainsHandler(domainsToRemove, domainsToAdd, shouldClearFirst);
+    RunLoop::main().dispatch([this, shouldClearFirst, protectedThis = makeRef(*this), domainsWithInteraction = crossThreadCopy(domainsWithInteraction), domainsWithoutInteraction = crossThreadCopy(domainsWithoutInteraction)] () {
+        m_updatePrevalentDomainsWithAndWithoutInteractionHandler(domainsWithInteraction, domainsWithoutInteraction, shouldClearFirst);
     });
 
     if (shouldClearFirst == ShouldClearFirst::Yes)
         resetCookiePartitioningState();
     else {
-        for (auto& domain : domainsToRemove)
+        for (auto& domain : domainsWithInteraction)
             ensureResourceStatisticsForPrimaryDomain(domain).isMarkedForCookiePartitioning = false;
     }
 
-    for (auto& domain : domainsToAdd)
+    for (auto& domain : domainsWithoutInteraction)
         ensureResourceStatisticsForPrimaryDomain(domain).isMarkedForCookiePartitioning = true;
 }
 
+void WebResourceLoadStatisticsStore::clearPartitioningStateForDomains(const Vector<String>& domains)
+{
+    ASSERT(!RunLoop::isMain());
+    if (domains.isEmpty())
+        return;
+
+    RunLoop::main().dispatch([this, protectedThis = makeRef(*this), domains = crossThreadCopy(domains)] () {
+        m_removeDomainsHandler(domains);
+    });
+
+    for (auto& domain : domains)
+        ensureResourceStatisticsForPrimaryDomain(domain).isMarkedForCookiePartitioning = false;
+}
+
 void WebResourceLoadStatisticsStore::resetCookiePartitioningState()
 {
     ASSERT(!RunLoop::isMain());
index 4e50fbf..bb51d27 100644 (file)
@@ -59,10 +59,11 @@ enum class ShouldClearFirst;
 
 class WebResourceLoadStatisticsStore final : public IPC::Connection::WorkQueueMessageReceiver {
 public:
-    using UpdateCookiePartitioningForDomainsHandler = WTF::Function<void(const Vector<String>& domainsToRemove, const Vector<String>& domainsToAdd, ShouldClearFirst)>;
-    static Ref<WebResourceLoadStatisticsStore> create(const String& resourceLoadStatisticsDirectory, Function<void (const String&)>&& testingCallback, UpdateCookiePartitioningForDomainsHandler&& updateCookiePartitioningForDomainsHandler = [](const Vector<String>&, const Vector<String>&, ShouldClearFirst) { })
+    using UpdatePrevalentDomainsWithAndWithoutInteractionHandler = WTF::Function<void(const Vector<String>& domainsWithInteraction, const Vector<String>& domainsWithoutInteraction, ShouldClearFirst)>;
+    using RemovePrevalentDomainsHandler = WTF::Function<void (const Vector<String>&)>;
+    static Ref<WebResourceLoadStatisticsStore> create(const String& resourceLoadStatisticsDirectory, Function<void (const String&)>&& testingCallback, UpdatePrevalentDomainsWithAndWithoutInteractionHandler&& updateCookiePartitioningForDomainsHandler = [](const Vector<String>&, const Vector<String>&, ShouldClearFirst) { }, RemovePrevalentDomainsHandler&& removeDomainsHandler = [] (const Vector<String>&) { })
     {
-        return adoptRef(*new WebResourceLoadStatisticsStore(resourceLoadStatisticsDirectory, WTFMove(testingCallback), WTFMove(updateCookiePartitioningForDomainsHandler)));
+        return adoptRef(*new WebResourceLoadStatisticsStore(resourceLoadStatisticsDirectory, WTFMove(testingCallback), WTFMove(updateCookiePartitioningForDomainsHandler), WTFMove(removeDomainsHandler)));
     }
 
     ~WebResourceLoadStatisticsStore();
@@ -96,6 +97,7 @@ public:
     void setSubresourceUniqueRedirectTo(const WebCore::URL& subresource, const WebCore::URL& hostNameRedirectedTo);
     void scheduleCookiePartitioningUpdate();
     void scheduleCookiePartitioningUpdateForDomains(const Vector<String>& domainsToRemove, const Vector<String>& domainsToAdd, ShouldClearFirst);
+    void scheduleClearPartitioningStateForDomains(const Vector<String>& domains);
     void scheduleStatisticsAndDataRecordsProcessing();
     void submitTelemetry();
     void scheduleCookiePartitioningStateReset();
@@ -130,7 +132,7 @@ public:
     void logTestingEvent(const String&);
 
 private:
-    WebResourceLoadStatisticsStore(const String&, Function<void (const String&)>&& testingCallback, UpdateCookiePartitioningForDomainsHandler&&);
+    WebResourceLoadStatisticsStore(const String&, Function<void (const String&)>&& testingCallback, UpdatePrevalentDomainsWithAndWithoutInteractionHandler&&, RemovePrevalentDomainsHandler&&);
 
     void removeDataRecords();
 
@@ -148,6 +150,7 @@ private:
     Vector<String> topPrivatelyControlledDomainsToRemoveWebsiteDataFor();
     void updateCookiePartitioning();
     void updateCookiePartitioningForDomains(const Vector<String>& domainsToRemove, const Vector<String>& domainsToAdd, ShouldClearFirst);
+    void clearPartitioningStateForDomains(const Vector<String>& domains);
     void mergeStatistics(Vector<WebCore::ResourceLoadStatistics>&&);
     WebCore::ResourceLoadStatistics& ensureResourceStatisticsForPrimaryDomain(const String&);
     void processStatisticsAndDataRecords();
@@ -180,7 +183,8 @@ private:
     ResourceLoadStatisticsPersistentStorage m_persistentStorage;
     Vector<OperatingDate> m_operatingDates;
 
-    UpdateCookiePartitioningForDomainsHandler m_updateCookiePartitioningForDomainsHandler;
+    UpdatePrevalentDomainsWithAndWithoutInteractionHandler m_updatePrevalentDomainsWithAndWithoutInteractionHandler;
+    RemovePrevalentDomainsHandler m_removeDomainsHandler;
 
     WallTime m_endOfGrandfatheringTimestamp;
     RunLoop::Timer<WebResourceLoadStatisticsStore> m_dailyTasksTimer;
index a4be2f7..667a619 100644 (file)
@@ -1114,10 +1114,16 @@ void WebsiteDataStore::removeDataForTopPrivatelyControlledDomains(OptionSet<Webs
 }
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
-void WebsiteDataStore::updateCookiePartitioningForTopPrivatelyOwnedDomains(const Vector<String>& domainsToRemove, const Vector<String>& domainsToAdd, ShouldClearFirst shouldClearFirst)
+void WebsiteDataStore::updatePrevalentDomainsWithAndWithoutInteraction(const Vector<String>& domainsWithInteraction, const Vector<String>& domainsWithoutInteraction, ShouldClearFirst shouldClearFirst)
 {
     for (auto& processPool : processPools())
-        processPool->sendToNetworkingProcess(Messages::NetworkProcess::UpdateCookiePartitioningForTopPrivatelyOwnedDomains(m_sessionID, domainsToRemove, domainsToAdd, shouldClearFirst == ShouldClearFirst::Yes));
+        processPool->sendToNetworkingProcess(Messages::NetworkProcess::UpdatePrevalentDomainsWithAndWithoutInteraction(m_sessionID, domainsWithInteraction, domainsWithoutInteraction, shouldClearFirst == ShouldClearFirst::Yes));
+}
+
+void WebsiteDataStore::removePrevalentDomains(const Vector<String>& domains)
+{
+    for (auto& processPool : processPools())
+        processPool->sendToNetworkingProcess(Messages::NetworkProcess::RemovePrevalentDomains(m_sessionID, domains));
 }
 #endif
 
@@ -1303,8 +1309,10 @@ void WebsiteDataStore::enableResourceLoadStatisticsAndSetTestingCallback(Functio
     }
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
-    m_resourceLoadStatistics = WebResourceLoadStatisticsStore::create(m_configuration.resourceLoadStatisticsDirectory, WTFMove(callback), [this] (const Vector<String>& domainsToRemove, const Vector<String>& domainsToAdd, ShouldClearFirst shouldClearFirst) {
-        updateCookiePartitioningForTopPrivatelyOwnedDomains(domainsToRemove, domainsToAdd, shouldClearFirst);
+    m_resourceLoadStatistics = WebResourceLoadStatisticsStore::create(m_configuration.resourceLoadStatisticsDirectory, WTFMove(callback), [this] (const Vector<String>& domainsWithInteraction, const Vector<String>& domainsWithoutInteraction, ShouldClearFirst shouldClearFirst) {
+        updatePrevalentDomainsWithAndWithoutInteraction(domainsWithInteraction, domainsWithoutInteraction, shouldClearFirst);
+    }, [this] (const Vector<String>& domainsToRemove) {
+        removePrevalentDomains(domainsToRemove);
     });
 #else
     m_resourceLoadStatistics = WebResourceLoadStatisticsStore::create(m_configuration.resourceLoadStatisticsDirectory, WTFMove(callback));
index 1cdb643..3ab66cd 100644 (file)
@@ -105,7 +105,8 @@ public:
     void removeDataForTopPrivatelyControlledDomains(OptionSet<WebsiteDataType>, OptionSet<WebsiteDataFetchOption>, const Vector<String>& topPrivatelyControlledDomains, Function<void(HashSet<String>&&)>&& completionHandler);
 
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
-    void updateCookiePartitioningForTopPrivatelyOwnedDomains(const Vector<String>& domainsToRemove, const Vector<String>& domainsToAdd, ShouldClearFirst);
+    void updatePrevalentDomainsWithAndWithoutInteraction(const Vector<String>& domainsWithInteraction, const Vector<String>& domainsWithoutInteraction, ShouldClearFirst);
+    void removePrevalentDomains(const Vector<String>& domains);
 #endif
     void networkProcessDidCrash();
     void resolveDirectoriesIfNecessary();