Diff
Modified: trunk/LayoutTests/ChangeLog (221682 => 221683)
--- trunk/LayoutTests/ChangeLog 2017-09-06 17:24:38 UTC (rev 221682)
+++ trunk/LayoutTests/ChangeLog 2017-09-06 17:30:50 UTC (rev 221683)
@@ -1,3 +1,15 @@
+2017-09-06 Brent Fulgham <[email protected]>
+
+ 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 <[email protected]>
Layout Test http/tests/preload/single_download_preload.html is flaky.
Added: trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction-expected.txt (0 => 221683)
--- trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction-expected.txt 2017-09-06 17:30:50 UTC (rev 221683)
@@ -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
Added: trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction.html (0 => 221683)
--- trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction.html (rev 0)
+++ trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/third-party-cookie-with-and-without-user-interaction.html 2017-09-06 17:30:50 UTC (rev 221683)
@@ -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=""
+</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 = ""
+ 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 = "" + 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>
Modified: trunk/LayoutTests/platform/mac-highsierra-wk2/TestExpectations (221682 => 221683)
--- trunk/LayoutTests/platform/mac-highsierra-wk2/TestExpectations 2017-09-06 17:24:38 UTC (rev 221682)
+++ trunk/LayoutTests/platform/mac-highsierra-wk2/TestExpectations 2017-09-06 17:30:50 UTC (rev 221683)
@@ -6,6 +6,7 @@
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 ]
Modified: trunk/Source/WebCore/ChangeLog (221682 => 221683)
--- trunk/Source/WebCore/ChangeLog 2017-09-06 17:24:38 UTC (rev 221682)
+++ trunk/Source/WebCore/ChangeLog 2017-09-06 17:30:50 UTC (rev 221683)
@@ -1,3 +1,32 @@
+2017-09-06 Brent Fulgham <[email protected]>
+
+ 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 <[email protected]>
Missing break in URLParser
Modified: trunk/Source/WebCore/platform/network/NetworkStorageSession.h (221682 => 221683)
--- trunk/Source/WebCore/platform/network/NetworkStorageSession.h 2017-09-06 17:24:38 UTC (rev 221682)
+++ trunk/Source/WebCore/platform/network/NetworkStorageSession.h 2017-09-06 17:30:50 UTC (rev 221683)
@@ -90,8 +90,10 @@
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 @@
#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)
Modified: trunk/Source/WebCore/platform/network/cf/NetworkStorageSessionCFNet.cpp (221682 => 221683)
--- trunk/Source/WebCore/platform/network/cf/NetworkStorageSessionCFNet.cpp 2017-09-06 17:24:38 UTC (rev 221682)
+++ trunk/Source/WebCore/platform/network/cf/NetworkStorageSessionCFNet.cpp 2017-09-06 17:30:50 UTC (rev 221683)
@@ -205,23 +205,67 @@
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;
- if (!domainsToRemove.isEmpty()) {
- for (auto& domain : domainsToRemove)
- m_topPrivatelyControlledDomainsForCookiePartitioning.remove(domain);
+ 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();
}
-
- if (!domainsToAdd.isEmpty())
- m_topPrivatelyControlledDomainsForCookiePartitioning.add(domainsToAdd.begin(), domainsToAdd.end());
+
+ for (auto& domain : domainsWithInteraction) {
+ if (!clearFirst)
+ m_prevalentTopPrivatelyControlledDomainsWithoutInteraction.remove(domain);
+ m_prevalentTopPrivatelyControlledDomainsWithInteraction.add(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);
+ }
+}
+
#endif // HAVE(CFNETWORK_STORAGE_PARTITIONING)
#if !PLATFORM(COCOA)
Modified: trunk/Source/WebKit/ChangeLog (221682 => 221683)
--- trunk/Source/WebKit/ChangeLog 2017-09-06 17:24:38 UTC (rev 221682)
+++ trunk/Source/WebKit/ChangeLog 2017-09-06 17:30:50 UTC (rev 221683)
@@ -1,3 +1,42 @@
+2017-09-06 Brent Fulgham <[email protected]>
+
+ 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 <[email protected]>
[WPE][CMake] Fix path to the WebKitApplicationInfo.h header.
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (221682 => 221683)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp 2017-09-06 17:24:38 UTC (rev 221682)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp 2017-09-06 17:30:50 UTC (rev 221683)
@@ -319,11 +319,17 @@
}
#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
static void fetchDiskCacheEntries(PAL::SessionID sessionID, OptionSet<WebsiteDataFetchOption> fetchOptions, Function<void (Vector<WebsiteData::Entry>)>&& completionHandler)
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (221682 => 221683)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h 2017-09-06 17:24:38 UTC (rev 221682)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h 2017-09-06 17:30:50 UTC (rev 221683)
@@ -130,7 +130,8 @@
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; }
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in (221682 => 221683)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in 2017-09-06 17:24:38 UTC (rev 221682)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in 2017-09-06 17:30:50 UTC (rev 221683)
@@ -83,6 +83,7 @@
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
}
Modified: trunk/Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm (221682 => 221683)
--- trunk/Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm 2017-09-06 17:24:38 UTC (rev 221682)
+++ trunk/Source/WebKit/NetworkProcess/cocoa/NetworkDataTaskCocoa.mm 2017-09-06 17:30:50 UTC (rev 221683)
@@ -111,22 +111,30 @@
}
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
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm (221682 => 221683)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm 2017-09-06 17:24:38 UTC (rev 221682)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm 2017-09-06 17:30:50 UTC (rev 221683)
@@ -418,7 +418,7 @@
if (value)
store->scheduleCookiePartitioningUpdateForDomains({ }, { host }, WebKit::ShouldClearFirst::No);
else
- store->scheduleCookiePartitioningUpdateForDomains({ host }, { }, WebKit::ShouldClearFirst::No);
+ store->scheduleClearPartitioningStateForDomains({ host });
}
- (void)_resourceLoadStatisticsSubmitTelemetry
Modified: trunk/Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.cpp (221682 => 221683)
--- trunk/Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.cpp 2017-09-06 17:24:38 UTC (rev 221682)
+++ trunk/Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.cpp 2017-09-06 17:30:50 UTC (rev 221683)
@@ -145,10 +145,11 @@
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::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 @@
{
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());
Modified: trunk/Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.h (221682 => 221683)
--- trunk/Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.h 2017-09-06 17:24:38 UTC (rev 221682)
+++ trunk/Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.h 2017-09-06 17:30:50 UTC (rev 221683)
@@ -59,10 +59,11 @@
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 @@
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 @@
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 @@
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 @@
ResourceLoadStatisticsPersistentStorage m_persistentStorage;
Vector<OperatingDate> m_operatingDates;
- UpdateCookiePartitioningForDomainsHandler m_updateCookiePartitioningForDomainsHandler;
+ UpdatePrevalentDomainsWithAndWithoutInteractionHandler m_updatePrevalentDomainsWithAndWithoutInteractionHandler;
+ RemovePrevalentDomainsHandler m_removeDomainsHandler;
WallTime m_endOfGrandfatheringTimestamp;
RunLoop::Timer<WebResourceLoadStatisticsStore> m_dailyTasksTimer;
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp (221682 => 221683)
--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp 2017-09-06 17:24:38 UTC (rev 221682)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp 2017-09-06 17:30:50 UTC (rev 221683)
@@ -1114,11 +1114,17 @@
}
#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
void WebsiteDataStore::networkProcessDidCrash()
@@ -1303,8 +1309,10 @@
}
#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));
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h (221682 => 221683)
--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h 2017-09-06 17:24:38 UTC (rev 221682)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h 2017-09-06 17:30:50 UTC (rev 221683)
@@ -105,7 +105,8 @@
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();