Medium webkit Info Disclosure 🔧 Commit mapped

Overview

Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactProcessing maliciously crafted web content may disclose sensitive user information
DescriptionA permissions issue was addressed by removing the vulnerable code.
ComponentWebCore
Bug ClassInfo Disclosure
Tracker315121
Fix commit71730beeaf06 (webkit) +74/-117
CISA KEVNot listed
CreditedViggo Lekdorf
Disclosed2026-09-14

Background

Cache partition
WebKit’s memory cache (MemoryCache) keys resources by a partition string in addition to URL/session, to isolate a third party’s cached resources per top-level site (an anti-tracking / privacy boundary). A wrong partition key lets resources cached under one site be matched for another.
`domainForCachePartition()` (old model)
ScriptExecutionContext exposed domainForCachePartition() and a settable m_domainForCachePartition string; ResourceRequest::partitionName() derived a partition via PublicSuffixStore::topPrivatelyControlledDomain(domain). The partition was computed from a separately-stored domain string that callers set in several places.
`shouldBlockThirdPartyStorage()` (new model)
The patch replaces the stored domain string with a single boolean m_shouldBlockThirdPartyStorage carried on the request; the partition is then computed lazily from firstPartyForCookies() via RegistrableDomain.
`StorageBlockingPolicy::BlockThirdParty`
The setting under which third-party storage/cache is partitioned; otherwise the partition is empty (unpartitioned).

Root Cause Analysis

The old design stored a precomputed partition domain string (ScriptExecutionContext::m_domainForCachePartition, set via setDomainForCachePartition) and derived the cache partition from it through ResourceRequest::partitionName() → PublicSuffixStore::topPrivatelyControlledDomain(). That string was set from many independent call sites — DocumentLoader::loadMainResource (subframe vs main-frame branches), CachedResourceLoader, DOMURL::revokeObjectURL, LegacyWebArchive, InspectorResourceUtilities, Page::setupForRemoteWorker, and a dedicated manually-cached-image CachedImage constructor. Because the partition was cached, mutable, and set inconsistently across these paths (and sometimes relative to the subframe’s own document rather than the top document), a resource could be stored or looked up under a partition that did not match the real first party. The result is a partitioning (privacy isolation) failure: third-party cache state keyed under the wrong partition, allowing cross-site inference of cached resources — the “disclose sensitive user information” the advisory cites.

The patch removes the stored domain and its setters entirely and replaces them with a boolean intent (setShouldBlockThirdPartyStorage(...)), computing ResourceRequestBase::cachePartition() on demand: if third-party storage is not blocked it returns emptyString(), otherwise it returns RegistrableDomain(firstPartyForCookies()).string(). This makes the partition a pure function of the request’s actual first party plus the block-third-party policy, eliminating the possibility of a stale/mismatched partition string. Supporting changes make MemoryCache::removeResourcesWithOrigin(s) derive partitions through RegistrableDomain::uncheckedCreateFromHost (consistent with the new keying), drop the partitionName/setCachePartition API and the manually-cached CachedImage constructor that injected its own partition, and in Page::setupForRemoteWorker set the storage-blocking policy directly instead of a precomputed domain. Note the advisory calls this a “permissions issue … removing the vulnerable code”; the diff substantiates a cache-partition isolation weakness (a privacy/cross-site info-disclosure boundary), not a classic memory-safety bug.

Key insight
The cache partition was a mutable, separately-stored domain string set inconsistently across many loaders, so a resource could be keyed under the wrong partition; the fix derives the partition deterministically from the request’s firstPartyForCookies() and the block-third-party policy.

Attack Path

  1. Set up cross-site contexts Attacker controls (or embeds) content across two sites, one embedding the other as a third party, under a configuration where cache partitioning is expected to isolate them. (inferred: exact embedding to desync the stored partition is not shown by the diff.)
  2. Desync the stored partition Drive a load through a path that set m_domainForCachePartition from the wrong document/origin (e.g., subframe main-resource or manually cached image), so a resource is cached under a partition that does not match its true first party.
  3. Probe from another site From a different top-level site, issue a request whose derived partition collides with that mis-keyed entry.
  4. Observe a hit A cache hit (timing / load success) reveals that the target resource was previously loaded in the other context.
  5. Information disclosure Attacker infers cross-site browsing/cache state (sensitive user information) across what should be a partition boundary.

Impact Assessment

Operates in the WebContent (renderer) process over the in-process MemoryCache. No elevated privilege is required, but the primitive is a privacy / cross-site information disclosure (cache-partition isolation failure), not memory corruption or code execution — consistent with the advisory’s “disclose sensitive user information.” The concrete leak (which resource under which mismatched partition) is inferred from the keying change; the diff proves the partitioning logic was unreliable and centralizes it, but does not itself exhibit a working oracle. Strength: an inference/timing oracle over cache contents, gated by StorageBlockingPolicy::BlockThirdParty being the relevant isolation mode.

Changed Functions

FunctionChangeNotes
if
Source/WebCore/inspector/InspectorResourceUtilities.cpp
modified
if
Source/WebCore/loader/archive/cf/LegacyWebArchive.cpp
modified
if
Source/WebCore/loader/cache/CachedResourceLoader.cpp
modified
for
Source/WebCore/loader/cache/MemoryCache.cpp
modified

Files Changed

  • LayoutTests/ipc/create-socket-channel-invalid-url-crash.html
  • LayoutTests/ipc/invalid-url-network-data-task-crash.html
  • Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.cpp
  • Source/WebCore/dom/ScriptExecutionContext.cpp
  • Source/WebCore/dom/ScriptExecutionContext.h
  • Source/WebCore/html/DOMURL.cpp
  • Source/WebCore/inspector/InspectorResourceUtilities.cpp
  • Source/WebCore/loader/DocumentLoader.cpp
  • Source/WebCore/loader/archive/cf/LegacyWebArchive.cpp
  • Source/WebCore/loader/cache/CachedImage.cpp
  • Source/WebCore/loader/cache/CachedImage.h
  • Source/WebCore/loader/cache/CachedResource.h
  • Source/WebCore/loader/cache/CachedResourceLoader.cpp
  • Source/WebCore/loader/cache/CachedResourceRequest.cpp
  • Source/WebCore/loader/cache/CachedResourceRequest.h
  • Source/WebCore/loader/cache/MemoryCache.cpp
  • Source/WebCore/page/Page.cpp
  • Source/WebCore/platform/network/ResourceRequestBase.cpp
  • Source/WebCore/platform/network/ResourceRequestBase.h
  • Source/WebCore/platform/network/cf/ResourceRequest.h
  • Source/WebCore/platform/network/cocoa/ResourceRequestCocoa.mm
  • Source/WebCore/testing/Internals.cpp
  • Source/WebCore/workers/service/ServiceWorkerContainer.cpp
  • Source/WebCore/workers/service/ServiceWorkerJobData.cpp
  • Source/WebCore/workers/service/ServiceWorkerJobData.h
  • Source/WebCore/workers/service/server/SWServer.cpp
  • Source/WebCore/xml/XMLHttpRequest.cpp
  • Source/WebKit/NetworkProcess/NetworkProcess.cpp
  • Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp
  • Source/WebKit/NetworkProcess/cache/AsyncRevalidation.cpp
  • Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp
  • Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in
  • Source/WebKit/Shared/WebCoreArgumentCodersPlatform.serialization.in

Audit Directions

  • Remaining partition assumptions
    Audit any code still assuming cachePartition() returns a stored string (e.g., persistent/disk cache, network-process cache keying) for consistency with the new “derive from firstPartyForCookies” model.
  • `firstPartyForCookies` correctness
    Since the partition now depends entirely on firstPartyForCookies(), review paths that build requests without setting it correctly (synthetic requests, inspector, web-archive, object-URL revocation).
  • Manually/substitute-cached resources
    Re-examine other manual CachedResource insertion paths (substitute data, archives) for partition keys that bypass the centralized derivation.
  • Cross-site cache oracles
    Look for other caches (preload, font, image-decode) keyed on a domain string rather than the registrable first party.
diff --git a/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.cpp b/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.cpp
index 8a514e3f1b02..af98afce6990 100644
--- a/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.cpp
+++ b/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.cpp
@@ -110,7 +110,7 @@ std::optional<ResourceRequest> ThreadableWebSocketChannel::webSocketConnectReque
     auto userAgent = document.userAgent(validatedURL->url);
     ResourceRequest request { WTF::move(validatedURL->url) };
     request.setHTTPUserAgent(userAgent);
-    request.setDomainForCachePartition(document.domainForCachePartition());
+    request.setShouldBlockThirdPartyStorage(document.shouldBlockThirdPartyStorage());
     request.setAllowCookies(validatedURL->areCookiesAllowed);
     request.setFirstPartyForCookies(document.firstPartyForCookies());
     request.setHTTPHeaderField(HTTPHeaderName::Origin, protect(document.securityOrigin())->toString());
diff --git a/Source/WebCore/dom/ScriptExecutionContext.cpp b/Source/WebCore/dom/ScriptExecutionContext.cpp
index 68f521e95f63..dccb833bd660 100644
--- a/Source/WebCore/dom/ScriptExecutionContext.cpp
+++ b/Source/WebCore/dom/ScriptExecutionContext.cpp
@@ -752,15 +752,17 @@ JSC::JSGlobalObject* ScriptExecutionContext::globalObject() const
 
 String ScriptExecutionContext::domainForCachePartition() const
 {
-    if (!m_domainForCachePartition.isNull())
-        return m_domainForCachePartition;
-
     if (m_storageBlockingPolicy != StorageBlockingPolicy::BlockThirdParty)
         return emptyString();
 
     return protect(topOrigin())->domainForCachePartition();
 }
 
+bool ScriptExecutionContext::shouldBlockThirdPartyStorage() const
+{
+    return m_storageBlockingPolicy == StorageBlockingPolicy::BlockThirdParty;
+}
+
 bool ScriptExecutionContext::allowsMediaDevices() const
 {
 #if ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/dom/ScriptExecutionContext.h b/Source/WebCore/dom/ScriptExecutionContext.h
index 971217440298..1685f90c8507 100644
--- a/Source/WebCore/dom/ScriptExecutionContext.h
+++ b/Source/WebCore/dom/ScriptExecutionContext.h
@@ -342,7 +342,6 @@ public:
     WEBCORE_EXPORT JSC::JSGlobalObject* globalObject() const;
 
     WEBCORE_EXPORT String domainForCachePartition() const;
-    void setDomainForCachePartition(String&& domain) { m_domainForCachePartition = WTF::move(domain); }
 
     bool allowsMediaDevices() const;
     ServiceWorker* activeServiceWorker() const { return m_activeServiceWorker.get(); }
@@ -367,6 +366,8 @@ public:
     void setHasLoggedAuthenticatedEncryptionWarning(bool value) { m_hasLoggedAuthenticatedEncryptionWarning = value; }
 
     void setStorageBlockingPolicy(StorageBlockingPolicy policy) { m_storageBlockingPolicy = policy; }
+    WEBCORE_EXPORT bool shouldBlockThirdPartyStorage() const;
+
     enum class ResourceType : uint8_t {
         Cookies,
         Geolocation,
@@ -464,7 +465,6 @@ private:
     RefPtr<ServiceWorker> m_activeServiceWorker;
     HashMap<ServiceWorkerIdentifier, WeakRef<ServiceWorker, WeakPtrImplWithEventTargetData>> m_serviceWorkers;
 
-    String m_domainForCachePartition;
     mutable ScriptExecutionContextIdentifier m_identifier;
 
     HashMap<NotificationCallbackIdentifier, CompletionHandler<void()>> m_notificationCallbacks;
diff --git a/Source/WebCore/html/DOMURL.cpp b/Source/WebCore/html/DOMURL.cpp
index 4bd5be980b98..e6786c54f253 100644
--- a/Source/WebCore/html/DOMURL.cpp
+++ b/Source/WebCore/html/DOMURL.cpp
@@ -124,7 +124,7 @@ void DOMURL::revokeObjectURL(ScriptExecutionContext& scriptExecutionContext, con
 {
     URL url { urlString };
     ResourceRequest request(WTF::move(url));
-    request.setDomainForCachePartition(scriptExecutionContext.domainForCachePartition());
+    request.setShouldBlockThirdPartyStorage(scriptExecutionContext.shouldBlockThirdPartyStorage());
 
     MemoryCache::removeRequestFromSessionCaches(scriptExecutionContext, request);
 
diff --git a/Source/WebCore/inspector/InspectorResourceUtilities.cpp b/Source/WebCore/inspector/InspectorResourceUtilities.cpp
index 69a787e50326..af77e8327ce7 100644
--- a/Source/WebCore/inspector/InspectorResourceUtilities.cpp
+++ b/Source/WebCore/inspector/InspectorResourceUtilities.cpp
@@ -249,7 +249,7 @@ RefPtr<CachedResource> cachedResource(const LocalFrame* frame, const URL& url)
     RefPtr cachedResource = protect(frame->document())->cachedResourceLoader().cachedResource(MemoryCache::removeFragmentIdentifierIfNeeded(url));
     if (!cachedResource) {
         ResourceRequest request(URL { url });
-        request.setDomainForCachePartition(protect(frame->document())->domainForCachePartition());
+        request.setShouldBlockThirdPartyStorage(protect(frame->document())->shouldBlockThirdPartyStorage());
         cachedResource = MemoryCache::singleton().resourceForRequest(request, frame->page()->sessionID());
     }
 
diff --git a/Source/WebCore/loader/DocumentLoader.cpp b/Source/WebCore/loader/DocumentLoader.cpp
index 7114a9d4dd70..dc7bc200a9e4 100644
--- a/Source/WebCore/loader/DocumentLoader.cpp
+++ b/Source/WebCore/loader/DocumentLoader.cpp
@@ -2311,17 +2311,10 @@ void DocumentLoader::loadMainResource(ResourceRequest&& request)
     }
 
     CachedResourceRequest mainResourceRequest(WTF::move(request), mainResourceLoadOptions);
-    if (!frame->isMainFrame() && frame->document()) {
-        // If we are loading the main resource of a subframe, use the cache partition of the main document.
-        mainResourceRequest.setDomainForCachePartition(*protect(frame->document()));
-    } else {
-        if (frameLoader()->frame().settings().storageBlockingPolicy() != StorageBlockingPolicy::BlockThirdParty)
-            mainResourceRequest.setDomainForCachePartition(emptyString());
-        else {
-            auto origin = SecurityOrigin::create(mainResourceRequest.resourceRequest().url());
-            mainResourceRequest.setDomainForCachePartition(origin->domainForCachePartition());
-        }
-    }
+    if (!frame->isMainFrame() && frame->document())
+        mainResourceRequest.resourceRequest().setShouldBlockThirdPartyStorage(protect(frame->document())->shouldBlockThirdPartyStorage());
+    else
+        mainResourceRequest.resourceRequest().setShouldBlockThirdPartyStorage(frameLoader()->frame().settings().storageBlockingPolicy() == StorageBlockingPolicy::BlockThirdParty);
 
     auto mainResourceOrError = m_cachedResourceLoader->requestMainResource(WTF::move(mainResourceRequest));
 
diff --git a/Source/WebCore/loader/archive/cf/LegacyWebArchive.cpp b/Source/WebCore/loader/archive/cf/LegacyWebArchive.cpp
index 097cf5d2c1b3..40f3767097e6 100644
--- a/Source/WebCore/loader/archive/cf/LegacyWebArchive.cpp
+++ b/Source/WebCore/loader/archive/cf/LegacyWebArchive.cpp
@@ -772,7 +772,10 @@ RefPtr<LegacyWebArchive> LegacyWebArchive::createInternal(const String& markupSt
                 auto resource = documentLoader->subresource(subresourceURL);
                 if (!resource) {
                     ResourceRequest request(URL { subresourceURL });
-                    request.setDomainForCachePartition(protect(frame.document())->domainForCachePartition());
+                    if (RefPtr document = frame.document()) {
+                        request.setShouldBlockThirdPartyStorage(document->shouldBlockThirdPartyStorage());
+                        request.setFirstPartyForCookies(document->firstPartyForCookies());
+                    }
                     if (RefPtr cachedResource = MemoryCache::singleton().resourceForRequest(request, frame.page()->sessionID()))
                         resource = ArchiveResource::create(cachedResource->resourceBuffer(), subresourceURL, cachedResource->response());
                 }
diff --git a/Source/WebCore/loader/cache/CachedImage.cpp b/Source/WebCore/loader/cache/CachedImage.cpp
index 838710d85d7c..ad434e9654ce 100644
--- a/Source/WebCore/loader/cache/CachedImage.cpp
+++ b/Source/WebCore/loader/cache/CachedImage.cpp
@@ -87,23 +87,6 @@ CachedImage::CachedImage(Image* image, PAL::SessionID sessionID, const CookieJar
 {
 }
 
-CachedImage::CachedImage(const URL& url, Image* image, PAL::SessionID sessionID, const CookieJar* cookieJar, const String& domainForCachePartition)
-    : CachedResource(url, Type::ImageResource, sessionID, cookieJar)
-    , m_image(image)
-    , m_updateImageDataCount(0)
-    , m_isManuallyCached(true)
-    , m_shouldPaintBrokenImage(true)
-    , m_forceUpdateImageDataEnabledForTesting(false)
-{
-    m_resourceRequest.setDomainForCachePartition(domainForCachePartition);
-
-    // Use the incoming URL in the response field. This ensures that code using the response directly,
-    // such as origin checks for security, actually see something.
-    mutableResponse().setURL(URL { url });
-
-    setAllowsOrientationOverride(isCORSSameOrigin() || protect(m_image)->sourceURL().protocolIsData());
-}
-
 CachedImage::~CachedImage()
 {
     clearImage();
diff --git a/Source/WebCore/loader/cache/CachedImage.h b/Source/WebCore/loader/cache/CachedImage.h
index f161c14577b3..53d3d643a391 100644
--- a/Source/WebCore/loader/cache/CachedImage.h
+++ b/Source/WebCore/loader/cache/CachedImage.h
@@ -48,8 +48,6 @@ class CachedImage final : public CachedResource {
 public:
     CachedImage(CachedResourceRequest&&, PAL::SessionID, const CookieJar*);
     CachedImage(Image*, PAL::SessionID, const CookieJar*);
-    // Constructor to use for manually cached images.
-    CachedImage(const URL&, Image*, PAL::SessionID, const CookieJar*, const String& domainForCachePartition);
     virtual ~CachedImage();
 
     WEBCORE_EXPORT Image* image() const; // Returns the nullImage() if the image is not available yet.
diff --git a/Source/WebCore/loader/cache/CachedResource.h b/Source/WebCore/loader/cache/CachedResource.h
index f844bb1ac4b2..85766237f676 100644
--- a/Source/WebCore/loader/cache/CachedResource.h
+++ b/Source/WebCore/loader/cache/CachedResource.h
@@ -139,7 +139,7 @@ public:
 
     const ResourceRequest& resourceRequest() const LIFETIME_BOUND { return m_resourceRequest; }
     const URL& url() const LIFETIME_BOUND { return m_resourceRequest.url(); }
-    const String& cachePartition() const LIFETIME_BOUND { return m_resourceRequest.cachePartition(); }
+    String cachePartition() const { return m_resourceRequest.cachePartition(); }
     PAL::SessionID sessionID() const { return m_sessionID; }
     const CookieJar* cookieJar() const { return m_cookieJar.get(); }
     Type type() const { return m_type; }
diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.cpp b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
index 7ba791c9e10e..a8aaad053606 100644
--- a/Source/WebCore/loader/cache/CachedResourceLoader.cpp
+++ b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
@@ -316,7 +316,7 @@ CachedResourceHandle<CachedCSSStyleSheet> CachedResourceLoader::requestUserCSSSt
 
     ASSERT(document());
     if (RefPtr document = this->document())
-        request.setDomainForCachePartition(*document);
+        request.resourceRequest().setShouldBlockThirdPartyStorage(document->shouldBlockThirdPartyStorage());
 
     Ref memoryCache = MemoryCache::singleton();
     if (request.allowsCaching()) {
@@ -1267,7 +1267,7 @@ ResourceErrorOr<Ref<CachedResource>> CachedResourceLoader::requestResource(Cache
     RefPtr<CachedResource> resource;
     CheckedPtr<ContentSecurityPolicy> contentSecurityPolicy;
     if (document) {
-        request.setDomainForCachePartition(*document);
+        request.resourceRequest().setShouldBlockThirdPartyStorage(document->shouldBlockThirdPartyStorage());
         request.resourceRequest().setFirstPartyForCookies(document->firstPartyForCookies());
         contentSecurityPolicy = document->contentSecurityPolicy();
     }
diff --git a/Source/WebCore/loader/cache/CachedResourceRequest.cpp b/Source/WebCore/loader/cache/CachedResourceRequest.cpp
index e2fb2e6e79f5..b92d5675626b 100644
--- a/Source/WebCore/loader/cache/CachedResourceRequest.cpp
+++ b/Source/WebCore/loader/cache/CachedResourceRequest.cpp
@@ -125,16 +125,6 @@ void CachedResourceRequest::upgradeInsecureRequestIfNeeded(Document& document, C
     upgradeInsecureResourceRequestIfNeeded(m_resourceRequest, document, alwaysUpgradeRequest);
 }
 
-void CachedResourceRequest::setDomainForCachePartition(Document& document)
-{
-    m_resourceRequest.setDomainForCachePartition(document.domainForCachePartition());
-}
-
-void CachedResourceRequest::setDomainForCachePartition(const String& domain)
-{
-    m_resourceRequest.setDomainForCachePartition(domain);
-}
-
 static inline void appendAdditionalSupportedImageMIMETypes(StringBuilder& acceptHeader)
 {
     for (const auto& additionalSupportedImageMIMEType : MIMETypeRegistry::additionalSupportedImageMIMETypes()) {
diff --git a/Source/WebCore/loader/cache/CachedResourceRequest.h b/Source/WebCore/loader/cache/CachedResourceRequest.h
index a8592edeed15..b0790088fc0d 100644
--- a/Source/WebCore/loader/cache/CachedResourceRequest.h
+++ b/Source/WebCore/loader/cache/CachedResourceRequest.h
@@ -97,8 +97,6 @@ public:
 #if ENABLE(CONTENT_EXTENSIONS)
     void applyResults(ContentRuleListResults&&, Page*);
 #endif
-    void setDomainForCachePartition(Document&);
-    void setDomainForCachePartition(const String&);
     bool isLinkPreload() const { return m_isLinkPreload; }
     void setIsLinkPreload() { m_isLinkPreload = true; }
 
diff --git a/Source/WebCore/loader/cache/MemoryCache.cpp b/Source/WebCore/loader/cache/MemoryCache.cpp
index 9ce7da4c07e1..599c46a2f192 100644
--- a/Source/WebCore/loader/cache/MemoryCache.cpp
+++ b/Source/WebCore/loader/cache/MemoryCache.cpp
@@ -35,7 +35,7 @@
 #include "Image.h"
 #include "LocalFrameView.h"
 #include "Logging.h"
-#include "PublicSuffixStore.h"
+#include "RegistrableDomain.h"
 #include "SharedBuffer.h"
 #include "WorkerGlobalScope.h"
 #include "WorkerLoaderProxy.h"
@@ -559,14 +559,16 @@ void MemoryCache::removeResourcesWithOrigin(const SecurityOrigin& origin, const
 void MemoryCache::removeResourcesWithOrigin(const SecurityOrigin& origin)
 {
     RELEASE_ASSERT(isMainThread());
-    String originPartition = ResourceRequest::partitionName(origin.host());
+    RegistrableDomain domain = RegistrableDomain::uncheckedCreateFromHost(origin.host());
+    String originPartition = domain.isEmpty() ? emptyString() : domain.string();
     removeResourcesWithOrigin(origin, originPartition);
 }
 
 void MemoryCache::removeResourcesWithOrigin(const ClientOrigin& origin)
 {
     RELEASE_ASSERT(isMainThread());
-    auto cachePartition = origin.topOrigin == origin.clientOrigin ? emptyString() : ResourceRequest::partitionName(origin.topOrigin.host());
+    RegistrableDomain topDomain = RegistrableDomain::uncheckedCreateFromHost(origin.topOrigin.host());
+    auto cachePartition = origin.topOrigin == origin.clientOrigin ? emptyString() : (topDomain.isEmpty() ? emptyString() : topDomain.string());
     removeResourcesWithOrigin(origin.clientOrigin.securityOrigin(), cachePartition);
 }
 
@@ -579,8 +581,10 @@ void MemoryCache::removeResourcesWithOrigins(PAL::SessionID sessionID, const Has
 
     HashSet<String> originPartitions;
 
-    for (auto& origin : origins)
-        originPartitions.add(ResourceRequest::partitionName(origin->host()));
+    for (auto& origin : origins) {
+        RegistrableDomain domain = RegistrableDomain::uncheckedCreateFromHost(origin->host());
+        originPartitions.add(domain.isEmpty() ? emptyString() : domain.string());
+    }
 
     Vector<WeakPtr<CachedResource>> resourcesToRemove;
     for (auto& keyValuePair : *resourceMap) {
diff --git a/Source/WebCore/page/Page.cpp b/Source/WebCore/page/Page.cpp
index e84090dce03b..f0ebdfe87782 100644
--- a/Source/WebCore/page/Page.cpp
+++ b/Source/WebCore/page/Page.cpp
@@ -5213,10 +5213,7 @@ void Page::setupForRemoteWorker(const URL& scriptURL, const SecurityOriginData&
     if (auto* documentLoader = localMainFrame->loader().documentLoader())
         documentLoader->setAdvancedPrivacyProtections(advancedPrivacyProtections);
 
-    if (document->settings().storageBlockingPolicy() != StorageBlockingPolicy::BlockThirdParty)
-        document->setDomainForCachePartition(String { emptyString() });
-    else
-        document->setDomainForCachePartition(origin->domainForCachePartition());
+    document->setStorageBlockingPolicy(document->settings().storageBlockingPolicy());
 
     if (auto policy = parseReferrerPolicy(referrerPolicy, ReferrerPolicySource::HTTPHeader))
         document->setReferrerPolicy(*policy);
diff --git a/Source/WebCore/platform/network/ResourceRequestBase.cpp b/Source/WebCore/platform/network/ResourceRequestBase.cpp
index b1c5e9185a02..e97d9f14885d 100644
--- a/Source/WebCore/platform/network/ResourceRequestBase.cpp
+++ b/Source/WebCore/platform/network/ResourceRequestBase.cpp
@@ -30,7 +30,6 @@
 #include "HTTPStatusCodes.h"
 #include "IPAddressSpace.h"
 #include "Logging.h"
-#include "PublicSuffixStore.h"
 #include "RegistrableDomain.h"
 #include "ResourceRequest.h"
 #include "ResourceResponse.h"
@@ -73,7 +72,7 @@ void ResourceRequestBase::setAsIsolatedCopy(const ResourceRequest& other)
     setPriority(other.priority());
     setRequester(other.requester());
     setInitiatorIdentifier(other.initiatorIdentifier().isolatedCopy());
-    setCachePartition(other.cachePartition().isolatedCopy());
+    setShouldBlockThirdPartyStorage(other.shouldBlockThirdPartyStorage());
 
     if (auto inspectorInitiatorNodeIdentifier = other.inspectorInitiatorNodeIdentifier())
         setInspectorInitiatorNodeIdentifier(*inspectorInitiatorNodeIdentifier);
@@ -860,25 +859,18 @@ unsigned initializeMaximumHTTPConnectionCountPerHost()
 }
 #endif
 
-void ResourceRequestBase::setCachePartition(const String& cachePartition)
+String ResourceRequestBase::cachePartition() const
 {
 #if ENABLE(CACHE_PARTITIONING)
-    ASSERT(!cachePartition.isNull());
-    ASSERT(cachePartition == partitionName(cachePartition));
-    m_cachePartition = cachePartition;
-#else
-    UNUSED_PARAM(cachePartition);
-#endif
-}
-
-String ResourceRequestBase::partitionName(const String& domain)
-{
-    if (domain.isNull())
+    if (!m_shouldBlockThirdPartyStorage)
         return emptyString();
-    auto highLevel = PublicSuffixStore::singleton().topPrivatelyControlledDomain(domain);
-    if (highLevel.isNull())
+    RegistrableDomain domain(firstPartyForCookies());
+    if (domain.isEmpty())
         return emptyString();
-    return highLevel;
+    return domain.string();
+#else
+    return emptyString();
+#endif
 }
 
 bool ResourceRequestBase::isThirdParty() const
diff --git a/Source/WebCore/platform/network/ResourceRequestBase.h b/Source/WebCore/platform/network/ResourceRequestBase.h
index c61a59848677..3edfb655bb7e 100644
--- a/Source/WebCore/platform/network/ResourceRequestBase.h
+++ b/Source/WebCore/platform/network/ResourceRequestBase.h
@@ -239,10 +239,9 @@ public:
     WEBCORE_EXPORT ResourceLoadPriority priority() const;
     WEBCORE_EXPORT void setPriority(ResourceLoadPriority);
 
-    WEBCORE_EXPORT static String partitionName(const String& domain);
-    const String& cachePartition() const LIFETIME_BOUND { return m_cachePartition; }
-    WEBCORE_EXPORT void setCachePartition(const String&);
-    void setDomainForCachePartition(const String& domain) { setCachePartition(partitionName(domain)); }
+    WEBCORE_EXPORT String cachePartition() const;
+    bool shouldBlockThirdPartyStorage() const { return m_shouldBlockThirdPartyStorage; }
+    void setShouldBlockThirdPartyStorage(bool value) { m_shouldBlockThirdPartyStorage = value; }
 
     WEBCORE_EXPORT bool isConditional() const;
     WEBCORE_EXPORT void makeUnconditional();
@@ -328,13 +327,13 @@ protected:
     
     RequestData m_requestData;
     String m_initiatorIdentifier;
-    String m_cachePartition { emptyString() };
     RefPtr<FormData> m_httpBody;
     std::optional<int> m_inspectorInitiatorNodeIdentifier;
     mutable bool m_resourceRequestUpdated : 1;
     mutable bool m_platformRequestUpdated : 1;
     mutable bool m_resourceRequestBodyUpdated : 1;
     mutable bool m_platformRequestBodyUpdated : 1;
+    bool m_shouldBlockThirdPartyStorage : 1 { true };
     bool m_hiddenFromInspector : 1;
 
 private:
diff --git a/Source/WebCore/platform/network/cf/ResourceRequest.h b/Source/WebCore/platform/network/cf/ResourceRequest.h
index 5963aed43cec..7ff979f9a404 100644
--- a/Source/WebCore/platform/network/cf/ResourceRequest.h
+++ b/Source/WebCore/platform/network/cf/ResourceRequest.h
@@ -78,16 +78,16 @@ public:
     
... (file diff truncated)
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/LayoutTests/ipc/create-socket-channel-invalid-url-crash.html b/LayoutTests/ipc/create-socket-channel-invalid-url-crash.html
index e245b9ccc7d1..282813efb6b7 100644
--- a/LayoutTests/ipc/create-socket-channel-invalid-url-crash.html
+++ b/LayoutTests/ipc/create-socket-channel-invalid-url-crash.html
@@ -35,7 +35,7 @@ setTimeout(async () => {
                     m_targetAddressSpace: 0
                 }
             },
-            cachePartition: '',
+            shouldBlockThirdPartyStorage: true,
             hiddenFromInspector: true
         },
         protocol: '',
diff --git a/LayoutTests/ipc/invalid-url-network-data-task-crash.html b/LayoutTests/ipc/invalid-url-network-data-task-crash.html
index 699fef1c915c..978d7afb6067 100644
--- a/LayoutTests/ipc/invalid-url-network-data-task-crash.html
+++ b/LayoutTests/ipc/invalid-url-network-data-task-crash.html
@@ -46,7 +46,7 @@ setTimeout(async () => {
                     m_targetAddressSpace: 0
                 }
             },
-            cachePartition: '',
+            shouldBlockThirdPartyStorage: true,
             hiddenFromInspector: true
         },
         pageID: IPC.pageID,
diff --git a/Source/WebCore/testing/Internals.cpp b/Source/WebCore/testing/Internals.cpp
index 97042eacda8c..7fc21f96c874 100644
--- a/Source/WebCore/testing/Internals.cpp
+++ b/Source/WebCore/testing/Internals.cpp
@@ -987,7 +987,7 @@ CachedResource* Internals::resourceFromMemoryCache(const String& url)
         return nullptr;
 
     ResourceRequest request(contextDocument()->encodingParseURL(url));
-    request.setDomainForCachePartition(contextDocument()->domainForCachePartition());
+    request.setShouldBlockThirdPartyStorage(contextDocument()->shouldBlockThirdPartyStorage());
 
     return MemoryCache::singleton().resourceForRequest(request, contextDocument()->page()->sessionID());
 }
Loading diff…