Resource Load Statistics: Immediately forward cookie access at user interaction when...
authorwilander@apple.com <wilander@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Mar 2018 02:05:56 +0000 (02:05 +0000)
committerwilander@apple.com <wilander@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Mar 2018 02:05:56 +0000 (02:05 +0000)
https://bugs.webkit.org/show_bug.cgi?id=183577
<rdar://problem/38266987>

Reviewed by Brent Fulgham.

Source/WebCore:

Tested manually on live websites.
No new automated tests because of a bug in WebKitTestRunner:
https://bugs.webkit.org/show_bug.cgi?id=183578
The event sender triggers gestures in the opener rather than
in the popup.

* dom/Document.cpp:
(WebCore::Document::removedLastRef):
    Clears the new m_primaryDomainsGrantedPageSpecificStorageAccess.
(WebCore::Document::hasGrantedPageSpecificStorageAccess):
(WebCore::Document::setHasGrantedPageSpecificStorageAccess):
* dom/Document.h:
    Added member m_primaryDomainsGrantedPageSpecificStorageAccess
    where we store domains that have been granted access.
* loader/ResourceLoadObserver.cpp:
(WebCore::ResourceLoadObserver::setGrantStorageAccessUnderOpenerCallback):
(WebCore::ResourceLoadObserver::logUserInteractionWithReducedTimeResolution):
    Now checks if there is a cross-origin opener and if so, immediately
    grants cookie access to the popup's domain if it is partitioned or
    blocked.
* loader/ResourceLoadObserver.h:
* platform/network/NetworkStorageSession.h:
    Added member m_pagesGrantedStorageAccess.
* platform/network/cf/NetworkStorageSessionCFNet.cpp:
(WebCore::NetworkStorageSession::cookieStoragePartition const):
(WebCore::NetworkStorageSession::hasStorageAccess const):
    Renamed from hasStorageAccessForFrame since the frameID now is optional.
(WebCore::NetworkStorageSession::grantStorageAccess):
    Renamed from grantStorageAccessForFrame since the frameID now is optional.
(WebCore::NetworkStorageSession::removeStorageAccessForAllFramesOnPage):
    Now removes the pageID entry in m_pagesGrantedStorageAccess.
(WebCore::NetworkStorageSession::hasStorageAccessForFrame const): Deleted.
    Renamed since the frameID now is optional.
(WebCore::NetworkStorageSession::grantStorageAccessForFrame): Deleted.
    Renamed since the frameID now is optional.

Source/WebKit:

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::hasStorageAccessForFrame):
    Now also checks for general page access.
(WebKit::NetworkProcess::grantStorageAccess):
    Renamed from grantStorageAccessForFrame since the frameID now is optional.
(WebKit::NetworkProcess::grantStorageAccessForFrame): Deleted.
    Renamed since the frameID now is optional.
* NetworkProcess/NetworkProcess.h:
    Renaming since the frameID now is optional.
* NetworkProcess/NetworkProcess.messages.in:
    Renaming since the frameID now is optional.
* NetworkProcess/NetworkResourceLoader.cpp:
(WebKit::NetworkResourceLoader::logCookieInformation):
    Consequence of function renaming.
* UIProcess/Network/NetworkProcessProxy.cpp:
(WebKit::NetworkProcessProxy::grantStorageAccess):
(WebKit::NetworkProcessProxy::grantStorageAccessForFrame): Deleted.
    Renaming since the frameID now is optional.
* UIProcess/Network/NetworkProcessProxy.h:
* UIProcess/WebResourceLoadStatisticsStore.cpp:
(WebKit::WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore):
    Renaming since the frameID now is optional.
(WebKit::WebResourceLoadStatisticsStore::requestStorageAccess):
    Handler renaming since the frameID now is optional.
(WebKit::WebResourceLoadStatisticsStore::grantStorageAccessUnderOpener):
    New function for that grants cookie access under a whole page.
* UIProcess/WebResourceLoadStatisticsStore.h:
    Member renaming since the frameID now is optional.
* UIProcess/WebResourceLoadStatisticsStore.messages.in:
    New message received straight from WebCore::ResourceLoadObserver.
* UIProcess/WebsiteData/WebsiteDataStore.cpp:
(WebKit::WebsiteDataStore::grantStorageAccessHandler):
    Renamed and made frameID optional.
(WebKit::WebsiteDataStore::enableResourceLoadStatisticsAndSetTestingCallback):
    Consequence of renaming and making frameID optional.
(WebKit::WebsiteDataStore::grantStorageAccessForFrameHandler): Deleted.
    Renamed and made frameID optional.
* UIProcess/WebsiteData/WebsiteDataStore.h:
* WebProcess/WebProcess.cpp:
(WebProcess::WebProcess):
    Now calls setGrantStorageAccessUnderOpenerCallback() on the shared
    WebCore::ResourceLoadObserver.

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

20 files changed:
Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/loader/ResourceLoadObserver.cpp
Source/WebCore/loader/ResourceLoadObserver.h
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/NetworkResourceLoader.cpp
Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp
Source/WebKit/UIProcess/Network/NetworkProcessProxy.h
Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.cpp
Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.h
Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.messages.in
Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h
Source/WebKit/WebProcess/WebProcess.cpp

index 39ea499..ad85c4d 100644 (file)
@@ -1,3 +1,47 @@
+2018-03-12  John Wilander  <wilander@apple.com>
+
+        Resource Load Statistics: Immediately forward cookie access at user interaction when there's an opener document
+        https://bugs.webkit.org/show_bug.cgi?id=183577
+        <rdar://problem/38266987>
+
+        Reviewed by Brent Fulgham.
+
+        Tested manually on live websites.
+        No new automated tests because of a bug in WebKitTestRunner:
+        https://bugs.webkit.org/show_bug.cgi?id=183578
+        The event sender triggers gestures in the opener rather than
+        in the popup.
+
+        * dom/Document.cpp:
+        (WebCore::Document::removedLastRef):
+            Clears the new m_primaryDomainsGrantedPageSpecificStorageAccess.
+        (WebCore::Document::hasGrantedPageSpecificStorageAccess):
+        (WebCore::Document::setHasGrantedPageSpecificStorageAccess):
+        * dom/Document.h:
+            Added member m_primaryDomainsGrantedPageSpecificStorageAccess
+            where we store domains that have been granted access.
+        * loader/ResourceLoadObserver.cpp:
+        (WebCore::ResourceLoadObserver::setGrantStorageAccessUnderOpenerCallback):
+        (WebCore::ResourceLoadObserver::logUserInteractionWithReducedTimeResolution):
+            Now checks if there is a cross-origin opener and if so, immediately
+            grants cookie access to the popup's domain if it is partitioned or
+            blocked. 
+        * loader/ResourceLoadObserver.h:
+        * platform/network/NetworkStorageSession.h:
+            Added member m_pagesGrantedStorageAccess.
+        * platform/network/cf/NetworkStorageSessionCFNet.cpp:
+        (WebCore::NetworkStorageSession::cookieStoragePartition const):
+        (WebCore::NetworkStorageSession::hasStorageAccess const):
+            Renamed from hasStorageAccessForFrame since the frameID now is optional.
+        (WebCore::NetworkStorageSession::grantStorageAccess):
+            Renamed from grantStorageAccessForFrame since the frameID now is optional.
+        (WebCore::NetworkStorageSession::removeStorageAccessForAllFramesOnPage):
+            Now removes the pageID entry in m_pagesGrantedStorageAccess.
+        (WebCore::NetworkStorageSession::hasStorageAccessForFrame const): Deleted.
+            Renamed since the frameID now is optional.
+        (WebCore::NetworkStorageSession::grantStorageAccessForFrame): Deleted.
+            Renamed since the frameID now is optional.
+
 2018-03-12  Tim Horton  <timothy_horton@apple.com>
 
         Stop using SDK conditionals to control feature definitions
index 9e0a288..40e93f2 100644 (file)
@@ -7622,6 +7622,17 @@ void Document::setHasFrameSpecificStorageAccess(bool value)
 {
     m_frame->loader().client().setHasFrameSpecificStorageAccess(value);
 }
+
+bool Document::hasGrantedPageSpecificStorageAccess(String& primaryDomain)
+{
+    return m_primaryDomainGrantedPageSpecificStorageAccess == primaryDomain;
+}
+
+void Document::setHasGrantedPageSpecificStorageAccess(String& primaryDomain)
+{
+    m_primaryDomainGrantedPageSpecificStorageAccess = primaryDomain;
+}
+
 #endif
 
 void Document::setConsoleMessageListener(RefPtr<StringCallback>&& listener)
index dbefd1d..f78f0c7 100644 (file)
@@ -1415,6 +1415,11 @@ public:
 
     JSC::ThreadLocalCache& threadLocalCache();
 
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+    bool hasGrantedPageSpecificStorageAccess(String& primaryDomain);
+    void setHasGrantedPageSpecificStorageAccess(String& primaryDomain);
+#endif
+
 protected:
     enum ConstructionFlags { Synthesized = 1, NonRenderedPlaceholder = 1 << 1 };
     Document(Frame*, const URL&, unsigned = DefaultDocumentClass, unsigned constructionFlags = 0);
@@ -1901,6 +1906,10 @@ private:
     HashSet<ApplicationStateChangeListener*> m_applicationStateChangeListeners;
     
     RefPtr<JSC::ThreadLocalCache> m_threadLocalCache;
+
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+    String m_primaryDomainGrantedPageSpecificStorageAccess { };
+#endif
 };
 
 Element* eventTargetElementForDocument(Document*);
index 9651307..7443efb 100644 (file)
@@ -108,6 +108,12 @@ void ResourceLoadObserver::setNotificationCallback(WTF::Function<void (Vector<Re
     m_notificationCallback = WTFMove(notificationCallback);
 }
 
+void ResourceLoadObserver::setGrantStorageAccessUnderOpenerCallback(WTF::Function<void(const String& domainReceivingUserInteraction, uint64_t openerPageID, const String& openerDomain)>&& callback)
+{
+    ASSERT(!m_grantStorageAccessUnderOpenerCallback);
+    m_grantStorageAccessUnderOpenerCallback = WTFMove(callback);
+}
+
 ResourceLoadObserver::ResourceLoadObserver()
     : m_notificationTimer(*this, &ResourceLoadObserver::notifyObserver)
 {
@@ -311,6 +317,25 @@ void ResourceLoadObserver::logUserInteractionWithReducedTimeResolution(const Doc
     statistics.lastSeen = newTime;
     statistics.mostRecentUserInteractionTime = newTime;
 
+#if HAVE(CFNETWORK_STORAGE_PARTITIONING)
+    if (auto* opener = document.frame()->loader().opener()) {
+        if (auto* openerDocument = opener->document()) {
+            if (auto* openerFrame = openerDocument->frame()) {
+                if (auto openerPageID = openerFrame->loader().client().pageID()) {
+                    auto openerUrl = openerDocument->url();
+                    auto openerPrimaryDomain = primaryDomain(openerUrl);
+                    if (domain != openerPrimaryDomain
+                        && !openerDocument->hasGrantedPageSpecificStorageAccess(domain)
+                        && !equalIgnoringASCIICase(openerUrl.string(), blankURL())) {
+                        openerDocument->setHasGrantedPageSpecificStorageAccess(domain);
+                        m_grantStorageAccessUnderOpenerCallback(domain, openerPageID.value(), openerPrimaryDomain);
+                    }
+                }
+            }
+        }
+    }
+#endif
+
     m_notificationTimer.stop();
     notifyObserver();
 
index 59f3293..b92dd5e 100644 (file)
@@ -61,6 +61,7 @@ public:
     WEBCORE_EXPORT String statisticsForOrigin(const String&);
 
     WEBCORE_EXPORT void setNotificationCallback(WTF::Function<void (Vector<ResourceLoadStatistics>&&)>&&);
+    WEBCORE_EXPORT void setGrantStorageAccessUnderOpenerCallback(WTF::Function<void(const String&, uint64_t, const String&)>&&);
 
     WEBCORE_EXPORT void notifyObserver();
     WEBCORE_EXPORT void clearState();
@@ -82,6 +83,7 @@ private:
     HashMap<String, ResourceLoadStatistics> m_resourceStatisticsMap;
     HashMap<String, WTF::WallTime> m_lastReportedUserInteractionMap;
     WTF::Function<void (Vector<ResourceLoadStatistics>&&)> m_notificationCallback;
+    WTF::Function<void(String, uint64_t, String)> m_grantStorageAccessUnderOpenerCallback;
     Timer m_notificationTimer;
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING) && !RELEASE_LOG_DISABLED
     uint64_t m_loggingCounter { 0 };
index 44076e7..c2a5f14 100644 (file)
@@ -104,9 +104,9 @@ public:
     WEBCORE_EXPORT String cookieStoragePartition(const URL& firstPartyForCookies, const URL& resource, std::optional<uint64_t> frameID, std::optional<uint64_t> pageID) const;
     WEBCORE_EXPORT void setPrevalentDomainsToPartitionOrBlockCookies(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, bool clearFirst);
     WEBCORE_EXPORT void removePrevalentDomains(const Vector<String>& domains);
-    WEBCORE_EXPORT bool hasStorageAccessForFrame(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID) const;
+    WEBCORE_EXPORT bool hasStorageAccess(const String& resourceDomain, const String& firstPartyDomain, std::optional<uint64_t> frameID, uint64_t pageID) const;
     WEBCORE_EXPORT Vector<String> getAllStorageAccessEntries() const;
-    WEBCORE_EXPORT void grantStorageAccessForFrame(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID);
+    WEBCORE_EXPORT void grantStorageAccess(const String& resourceDomain, const String& firstPartyDomain, std::optional<uint64_t> frameID, uint64_t pageID);
     WEBCORE_EXPORT void removeStorageAccessForFrame(uint64_t frameID, uint64_t pageID);
     WEBCORE_EXPORT void removeStorageAccessForAllFramesOnPage(uint64_t pageID);
 #endif
@@ -182,6 +182,7 @@ private:
     HashSet<String> m_topPrivatelyControlledDomainsToPartition;
     HashSet<String> m_topPrivatelyControlledDomainsToBlock;
     HashMap<uint64_t, HashMap<uint64_t, String, DefaultHash<uint64_t>::Hash, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>>, DefaultHash<uint64_t>::Hash, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>> m_framesGrantedStorageAccess;
+    HashMap<uint64_t, HashMap<String, String>, DefaultHash<uint64_t>::Hash, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>> m_pagesGrantedStorageAccess;
 #endif
 
 #if PLATFORM(COCOA)
index 5c1abb4..43a0509 100644 (file)
@@ -196,7 +196,7 @@ String NetworkStorageSession::cookieStoragePartition(const URL& firstPartyForCoo
     if (firstPartyDomain == resourceDomain)
         return emptyString();
 
-    if (frameID && pageID && hasStorageAccessForFrame(resourceDomain, firstPartyDomain, frameID.value(), pageID.value()))
+    if (pageID && hasStorageAccess(resourceDomain, firstPartyDomain, frameID, pageID.value()))
         return emptyString();
 
     return firstPartyDomain;
@@ -281,19 +281,25 @@ void NetworkStorageSession::removePrevalentDomains(const Vector<String>& domains
     }
 }
 
-bool NetworkStorageSession::hasStorageAccessForFrame(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID) const
+bool NetworkStorageSession::hasStorageAccess(const String& resourceDomain, const String& firstPartyDomain, std::optional<uint64_t> frameID, uint64_t pageID) const
 {
-    UNUSED_PARAM(firstPartyDomain);
+    if (frameID) {
+        auto framesGrantedIterator = m_framesGrantedStorageAccess.find(pageID);
+        if (framesGrantedIterator != m_framesGrantedStorageAccess.end()) {
+            auto it = framesGrantedIterator->value.find(frameID.value());
+            if (it != framesGrantedIterator->value.end() && it->value == resourceDomain)
+                return true;
+        }
+    }
 
-    auto it1 = m_framesGrantedStorageAccess.find(pageID);
-    if (it1 == m_framesGrantedStorageAccess.end())
-        return false;
+    auto pagesGrantedIterator = m_pagesGrantedStorageAccess.find(pageID);
+    if (pagesGrantedIterator != m_pagesGrantedStorageAccess.end()) {
+        auto it = pagesGrantedIterator->value.find(firstPartyDomain);
+        if (it != pagesGrantedIterator->value.end() && it->value == resourceDomain)
+            return true;
+    }
 
-    auto it2 = it1->value.find(frameID);
-    if (it2 == it1->value.end())
-        return false;
-    
-    return it2->value == resourceDomain;
+    return false;
 }
 
 Vector<String> NetworkStorageSession::getAllStorageAccessEntries() const
@@ -307,18 +313,35 @@ Vector<String> NetworkStorageSession::getAllStorageAccessEntries() const
     return entries;
 }
     
-void NetworkStorageSession::grantStorageAccessForFrame(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID)
+void NetworkStorageSession::grantStorageAccess(const String& resourceDomain, const String& firstPartyDomain, std::optional<uint64_t> frameID, uint64_t pageID)
 {
-    UNUSED_PARAM(firstPartyDomain);
+    if (!frameID) {
+        auto pagesGrantedIterator = m_pagesGrantedStorageAccess.find(pageID);
+        if (pagesGrantedIterator == m_pagesGrantedStorageAccess.end()) {
+            HashMap<String, String> entry;
+            entry.add(firstPartyDomain, resourceDomain);
+            m_pagesGrantedStorageAccess.add(pageID, entry);
+        } else {
+            auto firstPartyDomainIterator = pagesGrantedIterator->value.find(firstPartyDomain);
+            if (firstPartyDomainIterator == pagesGrantedIterator->value.end())
+                pagesGrantedIterator->value.add(firstPartyDomain, resourceDomain);
+            else
+                firstPartyDomainIterator->value = resourceDomain;
+        }
+        return;
+    }
 
-    auto it1 = m_framesGrantedStorageAccess.find(pageID);
-    if (it1 == m_framesGrantedStorageAccess.end()) {
+    auto pagesGrantedIterator = m_framesGrantedStorageAccess.find(pageID);
+    if (pagesGrantedIterator == m_framesGrantedStorageAccess.end()) {
         HashMap<uint64_t, String, DefaultHash<uint64_t>::Hash, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>> entry;
-        entry.add(frameID, resourceDomain);
+        entry.add(frameID.value(), resourceDomain);
         m_framesGrantedStorageAccess.add(pageID, entry);
     } else {
-        auto it2 = it1->value.find(frameID);
-        it2->value = resourceDomain;
+        auto framesGrantedIterator = pagesGrantedIterator->value.find(frameID.value());
+        if (framesGrantedIterator == pagesGrantedIterator->value.end())
+            pagesGrantedIterator->value.add(frameID.value(), resourceDomain);
+        else
+            framesGrantedIterator->value = resourceDomain;
     }
 }
 
@@ -333,6 +356,7 @@ void NetworkStorageSession::removeStorageAccessForFrame(uint64_t frameID, uint64
 
 void NetworkStorageSession::removeStorageAccessForAllFramesOnPage(uint64_t pageID)
 {
+    m_pagesGrantedStorageAccess.remove(pageID);
     m_framesGrantedStorageAccess.remove(pageID);
 }
 
index 3d94412..fe778f0 100644 (file)
@@ -1,3 +1,54 @@
+2018-03-12  John Wilander  <wilander@apple.com>
+
+        Resource Load Statistics: Immediately forward cookie access at user interaction when there's an opener document
+        https://bugs.webkit.org/show_bug.cgi?id=183577
+        <rdar://problem/38266987>
+
+        Reviewed by Brent Fulgham.
+
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::hasStorageAccessForFrame):
+            Now also checks for general page access.
+        (WebKit::NetworkProcess::grantStorageAccess):
+            Renamed from grantStorageAccessForFrame since the frameID now is optional.
+        (WebKit::NetworkProcess::grantStorageAccessForFrame): Deleted.
+            Renamed since the frameID now is optional.
+        * NetworkProcess/NetworkProcess.h:
+            Renaming since the frameID now is optional.
+        * NetworkProcess/NetworkProcess.messages.in:
+            Renaming since the frameID now is optional.
+        * NetworkProcess/NetworkResourceLoader.cpp:
+        (WebKit::NetworkResourceLoader::logCookieInformation):
+            Consequence of function renaming.
+        * UIProcess/Network/NetworkProcessProxy.cpp:
+        (WebKit::NetworkProcessProxy::grantStorageAccess):
+        (WebKit::NetworkProcessProxy::grantStorageAccessForFrame): Deleted.
+            Renaming since the frameID now is optional.
+        * UIProcess/Network/NetworkProcessProxy.h:
+        * UIProcess/WebResourceLoadStatisticsStore.cpp:
+        (WebKit::WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore):
+            Renaming since the frameID now is optional.
+        (WebKit::WebResourceLoadStatisticsStore::requestStorageAccess):
+            Handler renaming since the frameID now is optional.
+        (WebKit::WebResourceLoadStatisticsStore::grantStorageAccessUnderOpener):
+            New function for that grants cookie access under a whole page.
+        * UIProcess/WebResourceLoadStatisticsStore.h:
+            Member renaming since the frameID now is optional.
+        * UIProcess/WebResourceLoadStatisticsStore.messages.in:
+            New message received straight from WebCore::ResourceLoadObserver.
+        * UIProcess/WebsiteData/WebsiteDataStore.cpp:
+        (WebKit::WebsiteDataStore::grantStorageAccessHandler):
+            Renamed and made frameID optional.
+        (WebKit::WebsiteDataStore::enableResourceLoadStatisticsAndSetTestingCallback):
+            Consequence of renaming and making frameID optional.
+        (WebKit::WebsiteDataStore::grantStorageAccessForFrameHandler): Deleted.
+            Renamed and made frameID optional.
+        * UIProcess/WebsiteData/WebsiteDataStore.h:
+        * WebProcess/WebProcess.cpp:
+        (WebProcess::WebProcess):
+            Now calls setGrantStorageAccessUnderOpenerCallback() on the shared
+            WebCore::ResourceLoadObserver.
+
 2018-03-12  Tim Horton  <timothy_horton@apple.com>
 
         Stop using SDK conditionals to control feature definitions
index 2d68e74..edc899e 100644 (file)
@@ -368,7 +368,7 @@ void NetworkProcess::updatePrevalentDomainsToPartitionOrBlockCookies(PAL::Sessio
 void NetworkProcess::hasStorageAccessForFrame(PAL::SessionID sessionID, const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, uint64_t contextId)
 {
     if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
-        parentProcessConnection()->send(Messages::NetworkProcessProxy::StorageAccessRequestResult(networkStorageSession->hasStorageAccessForFrame(resourceDomain, firstPartyDomain, frameID, pageID), contextId), 0);
+        parentProcessConnection()->send(Messages::NetworkProcessProxy::StorageAccessRequestResult(networkStorageSession->hasStorageAccess(resourceDomain, firstPartyDomain, frameID, pageID), contextId), 0);
     else
         ASSERT_NOT_REACHED();
 }
@@ -381,12 +381,12 @@ void NetworkProcess::getAllStorageAccessEntries(PAL::SessionID sessionID, uint64
         ASSERT_NOT_REACHED();
 }
 
-void NetworkProcess::grantStorageAccessForFrame(PAL::SessionID sessionID, const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, uint64_t contextId)
+void NetworkProcess::grantStorageAccess(PAL::SessionID sessionID, const String& resourceDomain, const String& firstPartyDomain, std::optional<uint64_t> frameID, uint64_t pageID, uint64_t contextId)
 {
     bool isStorageGranted = false;
     if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID)) {
-        networkStorageSession->grantStorageAccessForFrame(resourceDomain, firstPartyDomain, frameID, pageID);
-        ASSERT(networkStorageSession->hasStorageAccessForFrame(resourceDomain, firstPartyDomain, frameID, pageID));
+        networkStorageSession->grantStorageAccess(resourceDomain, firstPartyDomain, frameID, pageID);
+        ASSERT(networkStorageSession->hasStorageAccess(resourceDomain, firstPartyDomain, frameID, pageID));
         isStorageGranted = true;
     } else
         ASSERT_NOT_REACHED();
index 23568f3..8b2f018 100644 (file)
@@ -139,7 +139,7 @@ public:
     void updatePrevalentDomainsToPartitionOrBlockCookies(PAL::SessionID, const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, bool shouldClearFirst);
     void hasStorageAccessForFrame(PAL::SessionID, const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, uint64_t contextId);
     void getAllStorageAccessEntries(PAL::SessionID, uint64_t contextId);
-    void grantStorageAccessForFrame(PAL::SessionID, const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, uint64_t contextId);
+    void grantStorageAccess(PAL::SessionID, const String& resourceDomain, const String& firstPartyDomain, std::optional<uint64_t> frameID, uint64_t pageID, uint64_t contextId);
     void removePrevalentDomains(PAL::SessionID, const Vector<String>& domains);
 #endif
 
index be9fd8e..4f9000d 100644 (file)
@@ -85,7 +85,7 @@ messages -> NetworkProcess LegacyReceiver {
     UpdatePrevalentDomainsToPartitionOrBlockCookies(PAL::SessionID sessionID, Vector<String> domainsToPartition, Vector<String> domainsToBlock, Vector<String> domainsToNeitherPartitionNorBlock, bool shouldClearFirst)
     HasStorageAccessForFrame(PAL::SessionID sessionID, String resourceDomain, String firstPartyDomain, uint64_t frameID, uint64_t pageID, uint64_t contextId)
     GetAllStorageAccessEntries(PAL::SessionID sessionID, uint64_t contextId)
-    GrantStorageAccessForFrame(PAL::SessionID sessionID, String resourceDomain, String firstPartyDomain, uint64_t frameID, uint64_t pageID, uint64_t contextId)
+    GrantStorageAccess(PAL::SessionID sessionID, String resourceDomain, String firstPartyDomain, std::optional<uint64_t> frameID, uint64_t pageID, uint64_t contextId)
     RemovePrevalentDomains(PAL::SessionID sessionID, Vector<String> domainsWithInteraction);
 #endif
 
index e42c907..a95e194 100644 (file)
@@ -786,7 +786,7 @@ void NetworkResourceLoader::logCookieInformation(const String& label, const void
     auto escapedFrameID = escapeIDForJSON(frameID);
     auto escapedPageID = escapeIDForJSON(pageID);
     auto escapedIdentifier = escapeIDForJSON(identifier);
-    bool hasStorageAccessForFrame = (frameID && pageID) ? networkStorageSession.hasStorageAccessForFrame(url.string(), partition.string(), frameID.value(), pageID.value()) : false;
+    bool hasStorageAccess = (frameID && pageID) ? networkStorageSession.hasStorageAccess(url.string(), partition.string(), frameID.value(), pageID.value()) : false;
 
 #define LOCAL_LOG_IF_ALLOWED(fmt, ...) RELEASE_LOG_IF(networkStorageSession.sessionID().isAlwaysOnLoggingAllowed(), Network, "%p - %s::" fmt, loggedObject, label.utf8().data(), ##__VA_ARGS__)
 #define LOCAL_LOG(str, ...) \
@@ -794,7 +794,7 @@ void NetworkResourceLoader::logCookieInformation(const String& label, const void
 
     LOCAL_LOG(R"({ "url": "%{public}s",)", escapedURL.utf8().data());
     LOCAL_LOG(R"(  "partition": "%{public}s",)", escapedPartition.utf8().data());
-    LOCAL_LOG(R"(  "hasStorageAccess": %{public}s,)", hasStorageAccessForFrame ? "true" : "false");
+    LOCAL_LOG(R"(  "hasStorageAccess": %{public}s,)", hasStorageAccess ? "true" : "false");
     LOCAL_LOG(R"(  "referer": "%{public}s",)", escapedReferrer.utf8().data());
     LOCAL_LOG(R"(  "cookies": [)");
 
index dd217f1..6348a56 100644 (file)
@@ -420,12 +420,12 @@ void NetworkProcessProxy::hasStorageAccessForFrame(PAL::SessionID sessionID, con
     send(Messages::NetworkProcess::HasStorageAccessForFrame(sessionID, resourceDomain, firstPartyDomain, frameID, pageID, contextId), 0);
 }
 
-void NetworkProcessProxy::grantStorageAccessForFrame(PAL::SessionID sessionID, const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void(bool)>&& callback)
+void NetworkProcessProxy::grantStorageAccess(PAL::SessionID sessionID, const String& resourceDomain, const String& firstPartyDomain, std::optional<uint64_t> frameID, uint64_t pageID, WTF::CompletionHandler<void(bool)>&& callback)
 {
     auto contextId = nextRequestStorageAccessContextId();
     auto addResult = m_storageAccessResponseCallbackMap.add(contextId, WTFMove(callback));
     ASSERT_UNUSED(addResult, addResult.isNewEntry);
-    send(Messages::NetworkProcess::GrantStorageAccessForFrame(sessionID, resourceDomain, firstPartyDomain, frameID, pageID, contextId), 0);
+    send(Messages::NetworkProcess::GrantStorageAccess(sessionID, resourceDomain, firstPartyDomain, frameID, pageID, contextId), 0);
 }
 
 void NetworkProcessProxy::storageAccessRequestResult(bool wasGranted, uint64_t contextId)
index 72f3c16..2e93342 100644 (file)
@@ -81,7 +81,7 @@ public:
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING)
     void hasStorageAccessForFrame(PAL::SessionID, const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, CompletionHandler<void(bool)>&& callback);
     void getAllStorageAccessEntries(PAL::SessionID, CompletionHandler<void(Vector<String>&& domains)>&&);
-    void grantStorageAccessForFrame(PAL::SessionID, const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, CompletionHandler<void(bool)>&& callback);
+    void grantStorageAccess(PAL::SessionID, const String& resourceDomain, const String& firstPartyDomain, std::optional<uint64_t> frameID, uint64_t pageID, CompletionHandler<void(bool)>&& callback);
 #endif
 
     void writeBlobToFilePath(const WebCore::URL&, const String& path, CompletionHandler<void(bool)>&& callback);
index ff03783..3ba7842 100644 (file)
@@ -154,12 +154,12 @@ static Vector<OperatingDate> mergeOperatingDates(const Vector<OperatingDate>& ex
     return mergedDates;
 }
 
-WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore(const String& resourceLoadStatisticsDirectory, Function<void(const String&)>&& testingCallback, bool isEphemeral, UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler&& updatePrevalentDomainsToPartitionOrBlockCookiesHandler, HasStorageAccessForFrameHandler&& hasStorageAccessForFrameHandler, GrantStorageAccessForFrameHandler&& grantStorageAccessForFrameHandler, RemovePrevalentDomainsHandler&& removeDomainsHandler)
+WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore(const String& resourceLoadStatisticsDirectory, Function<void(const String&)>&& testingCallback, bool isEphemeral, UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler&& updatePrevalentDomainsToPartitionOrBlockCookiesHandler, HasStorageAccessForFrameHandler&& hasStorageAccessForFrameHandler, GrantStorageAccessHandler&& grantStorageAccessHandler, RemovePrevalentDomainsHandler&& removeDomainsHandler)
     : m_statisticsQueue(WorkQueue::create("WebResourceLoadStatisticsStore Process Data Queue", WorkQueue::Type::Serial, WorkQueue::QOS::Utility))
     , m_persistentStorage(*this, resourceLoadStatisticsDirectory, isEphemeral ? ResourceLoadStatisticsPersistentStorage::IsReadOnly::Yes : ResourceLoadStatisticsPersistentStorage::IsReadOnly::No)
     , m_updatePrevalentDomainsToPartitionOrBlockCookiesHandler(WTFMove(updatePrevalentDomainsToPartitionOrBlockCookiesHandler))
     , m_hasStorageAccessForFrameHandler(WTFMove(hasStorageAccessForFrameHandler))
-    , m_grantStorageAccessForFrameHandler(WTFMove(grantStorageAccessForFrameHandler))
+    , m_grantStorageAccessHandler(WTFMove(grantStorageAccessHandler))
     , m_removeDomainsHandler(WTFMove(removeDomainsHandler))
     , m_dailyTasksTimer(RunLoop::main(), this, &WebResourceLoadStatisticsStore::performDailyTasks)
     , m_statisticsTestingCallback(WTFMove(testingCallback))
@@ -381,10 +381,28 @@ void WebResourceLoadStatisticsStore::requestStorageAccess(String&& subFrameHost,
 
         subFrameStatistic.timesAccessedAsFirstPartyDueToStorageAccessAPI++;
 
-        m_grantStorageAccessForFrameHandler(subFramePrimaryDomain, topFramePrimaryDomain, frameID, pageID, WTFMove(callback));
+        m_grantStorageAccessHandler(subFramePrimaryDomain, topFramePrimaryDomain, frameID, pageID, WTFMove(callback));
     });
 }
-    
+
+void WebResourceLoadStatisticsStore::grantStorageAccessUnderOpener(String&& domainReceivingUserInteraction, uint64_t openerPageID, String&& openerDomain)
+{
+    ASSERT(domainReceivingUserInteraction != openerDomain);
+    ASSERT(!RunLoop::isMain());
+
+    if (domainReceivingUserInteraction == openerDomain)
+        return;
+
+    auto& domainReceivingUserInteractionStatistic = ensureResourceStatisticsForPrimaryDomain(domainReceivingUserInteraction);
+    if (!shouldPartitionCookies(domainReceivingUserInteractionStatistic) && !shouldBlockCookies(domainReceivingUserInteractionStatistic))
+        return;
+
+    m_grantStorageAccessHandler(WTFMove(domainReceivingUserInteraction), WTFMove(openerDomain), std::nullopt, openerPageID, [](bool) { });
+#if !RELEASE_LOG_DISABLED
+    RELEASE_LOG_INFO_IF(m_debugLoggingEnabled, ResourceLoadStatisticsDebug, "Grant storage access for %s under opener %s.", domainReceivingUserInteraction.utf8().data(), openerDomain.utf8().data());
+#endif
+}
+
 void WebResourceLoadStatisticsStore::grandfatherExistingWebsiteData(CompletionHandler<void()>&& callback)
 {
     ASSERT(!RunLoop::isMain());
index 40f42d0..cfc91fa 100644 (file)
@@ -63,11 +63,11 @@ class WebResourceLoadStatisticsStore final : public IPC::Connection::WorkQueueMe
 public:
     using UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler = WTF::Function<void(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst)>;
     using HasStorageAccessForFrameHandler = WTF::Function<void(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, WTF::Function<void(bool hasAccess)>&& callback)>;
-    using GrantStorageAccessForFrameHandler = WTF::Function<void(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, WTF::Function<void(bool wasGranted)>&& callback)>;
+    using GrantStorageAccessHandler = WTF::Function<void(const String& resourceDomain, const String& firstPartyDomain, std::optional<uint64_t> frameID, uint64_t pageID, WTF::Function<void(bool wasGranted)>&& callback)>;
     using RemovePrevalentDomainsHandler = WTF::Function<void (const Vector<String>&)>;
-    static Ref<WebResourceLoadStatisticsStore> create(const String& resourceLoadStatisticsDirectory, Function<void (const String&)>&& testingCallback, bool isEphemeral, UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler&& updatePrevalentDomainsToPartitionOrBlockCookiesHandler = [](const WTF::Vector<String>&, const WTF::Vector<String>&, const WTF::Vector<String>&, ShouldClearFirst) { }, HasStorageAccessForFrameHandler&& hasStorageAccessForFrameHandler = [](const String&, const String&, uint64_t, uint64_t, WTF::Function<void(bool)>&&) { }, GrantStorageAccessForFrameHandler&& grantStorageAccessForFrameHandler = [](const String&, const String&, uint64_t, uint64_t, WTF::Function<void(bool)>&&) { }, RemovePrevalentDomainsHandler&& removeDomainsHandler = [] (const WTF::Vector<String>&) { })
+    static Ref<WebResourceLoadStatisticsStore> create(const String& resourceLoadStatisticsDirectory, Function<void (const String&)>&& testingCallback, bool isEphemeral, UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler&& updatePrevalentDomainsToPartitionOrBlockCookiesHandler = [](const WTF::Vector<String>&, const WTF::Vector<String>&, const WTF::Vector<String>&, ShouldClearFirst) { }, HasStorageAccessForFrameHandler&& hasStorageAccessForFrameHandler = [](const String&, const String&, uint64_t, uint64_t, WTF::Function<void(bool)>&&) { }, GrantStorageAccessHandler&& grantStorageAccessHandler = [](const String&, const String&, std::optional<uint64_t>, uint64_t, WTF::Function<void(bool)>&&) { }, RemovePrevalentDomainsHandler&& removeDomainsHandler = [] (const WTF::Vector<String>&) { })
     {
-        return adoptRef(*new WebResourceLoadStatisticsStore(resourceLoadStatisticsDirectory, WTFMove(testingCallback), isEphemeral, WTFMove(updatePrevalentDomainsToPartitionOrBlockCookiesHandler), WTFMove(hasStorageAccessForFrameHandler), WTFMove(grantStorageAccessForFrameHandler), WTFMove(removeDomainsHandler)));
+        return adoptRef(*new WebResourceLoadStatisticsStore(resourceLoadStatisticsDirectory, WTFMove(testingCallback), isEphemeral, WTFMove(updatePrevalentDomainsToPartitionOrBlockCookiesHandler), WTFMove(hasStorageAccessForFrameHandler), WTFMove(grantStorageAccessHandler), WTFMove(removeDomainsHandler)));
     }
 
     ~WebResourceLoadStatisticsStore();
@@ -85,6 +85,7 @@ public:
 
     void hasStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&& callback);
     void requestStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&& callback);
+    void grantStorageAccessUnderOpener(String&& domainReceivingUserInteraction, uint64_t openerPageID, String&& openerDomain);
     void requestStorageAccessCallback(bool wasGranted, uint64_t contextId);
 
     void processWillOpenConnection(WebProcessProxy&, IPC::Connection&);
@@ -150,7 +151,7 @@ public:
     void logTestingEvent(const String&);
 
 private:
-    WebResourceLoadStatisticsStore(const String&, Function<void(const String&)>&& testingCallback, bool isEphemeral, UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler&&, HasStorageAccessForFrameHandler&&, GrantStorageAccessForFrameHandler&&, RemovePrevalentDomainsHandler&&);
+    WebResourceLoadStatisticsStore(const String&, Function<void(const String&)>&& testingCallback, bool isEphemeral, UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler&&, HasStorageAccessForFrameHandler&&, GrantStorageAccessHandler&&, RemovePrevalentDomainsHandler&&);
 
     void removeDataRecords(CompletionHandler<void()>&&);
 
@@ -210,7 +211,7 @@ private:
 
     UpdatePrevalentDomainsToPartitionOrBlockCookiesHandler m_updatePrevalentDomainsToPartitionOrBlockCookiesHandler;
     HasStorageAccessForFrameHandler m_hasStorageAccessForFrameHandler;
-    GrantStorageAccessForFrameHandler m_grantStorageAccessForFrameHandler;
+    GrantStorageAccessHandler m_grantStorageAccessHandler;
     RemovePrevalentDomainsHandler m_removeDomainsHandler;
 
     WallTime m_endOfGrandfatheringTimestamp;
index eb8582d..0f5f0b8 100644 (file)
@@ -21,5 +21,6 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 messages -> WebResourceLoadStatisticsStore {
+    GrantStorageAccessUnderOpener(String domainReceivingUserInteraction, uint64_t openerPageID, String openerDomain)
     ResourceLoadStatisticsUpdated(Vector<WebCore::ResourceLoadStatistics> origins)
 }
index a1415de..d5f6063 100644 (file)
@@ -1208,10 +1208,10 @@ void WebsiteDataStore::getAllStorageAccessEntries(CompletionHandler<void(Vector<
         processPool->networkProcess()->getAllStorageAccessEntries(m_sessionID, WTFMove(callback));
 }
 
-void WebsiteDataStore::grantStorageAccessForFrameHandler(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void(bool wasGranted)>&& callback)
+void WebsiteDataStore::grantStorageAccessHandler(const String& resourceDomain, const String& firstPartyDomain, std::optional<uint64_t> frameID, uint64_t pageID, WTF::CompletionHandler<void(bool wasGranted)>&& callback)
 {
     for (auto& processPool : processPools())
-        processPool->networkProcess()->grantStorageAccessForFrame(m_sessionID, resourceDomain, firstPartyDomain, frameID, pageID, WTFMove(callback));
+        processPool->networkProcess()->grantStorageAccess(m_sessionID, resourceDomain, firstPartyDomain, frameID, pageID, WTFMove(callback));
 }
 
 void WebsiteDataStore::removePrevalentDomains(const Vector<String>& domains)
@@ -1442,8 +1442,8 @@ void WebsiteDataStore::enableResourceLoadStatisticsAndSetTestingCallback(Functio
         updatePrevalentDomainsToPartitionOrBlockCookies(domainsToPartition, domainsToBlock, domainsToNeitherPartitionNorBlock, shouldClearFirst);
     }, [this, protectedThis = makeRef(*this)] (const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void(bool hasAccess)>&& callback) {
         hasStorageAccessForFrameHandler(resourceDomain, firstPartyDomain, frameID, pageID, WTFMove(callback));
-    }, [this, protectedThis = makeRef(*this)] (const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void(bool wasGranted)>&& callback) {
-        grantStorageAccessForFrameHandler(resourceDomain, firstPartyDomain, frameID, pageID, WTFMove(callback));
+    }, [this, protectedThis = makeRef(*this)] (const String& resourceDomain, const String& firstPartyDomain, std::optional<uint64_t> frameID, uint64_t pageID, WTF::CompletionHandler<void(bool wasGranted)>&& callback) {
+        grantStorageAccessHandler(resourceDomain, firstPartyDomain, frameID, pageID, WTFMove(callback));
     }, [this, protectedThis = makeRef(*this)] (const Vector<String>& domainsToRemove) {
         removePrevalentDomains(domainsToRemove);
     });
index e6f4a78..b312b08 100644 (file)
@@ -126,7 +126,7 @@ public:
     void updatePrevalentDomainsToPartitionOrBlockCookies(const Vector<String>& domainsToPartition, const Vector<String>& domainsToBlock, const Vector<String>& domainsToNeitherPartitionNorBlock, ShouldClearFirst);
     void hasStorageAccessForFrameHandler(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void(bool hasAccess)>&& callback);
     void getAllStorageAccessEntries(CompletionHandler<void(Vector<String>&& domains)>&&);
-    void grantStorageAccessForFrameHandler(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void(bool wasGranted)>&& callback);
+    void grantStorageAccessHandler(const String& resourceDomain, const String& firstPartyDomain, std::optional<uint64_t> frameID, uint64_t pageID, WTF::CompletionHandler<void(bool wasGranted)>&& callback);
     void removePrevalentDomains(const Vector<String>& domains);
     void hasStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&& callback);
     void requestStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&& callback);
index 1716365..628f6ed 100644 (file)
@@ -206,6 +206,10 @@ WebProcess::WebProcess()
         parentProcessConnection()->send(Messages::WebResourceLoadStatisticsStore::ResourceLoadStatisticsUpdated(WTFMove(statistics)), 0);
     });
 
+    ResourceLoadObserver::shared().setGrantStorageAccessUnderOpenerCallback([this] (const String& domainReceivingUserInteraction, uint64_t openerPageID, const String& openerDomain) {
+        parentProcessConnection()->send(Messages::WebResourceLoadStatisticsStore::GrantStorageAccessUnderOpener(domainReceivingUserInteraction, openerPageID, openerDomain), 0);
+    });
+    
     Gigacage::disableDisablingPrimitiveGigacageIfShouldBeEnabled();
 }