CVE-2026-64753
Overview
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)
ScriptExecutionContextexposeddomainForCachePartition()and a settablem_domainForCachePartitionstring;ResourceRequest::partitionName()derived a partition viaPublicSuffixStore::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_shouldBlockThirdPartyStoragecarried on the request; the partition is then computed lazily fromfirstPartyForCookies()viaRegistrableDomain. - `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.
firstPartyForCookies() and the block-third-party policy.Attack Path
- 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.)
- Desync the stored partition
Drive a load through a path that set
m_domainForCachePartitionfrom 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. - Probe from another site From a different top-level site, issue a request whose derived partition collides with that mis-keyed entry.
- Observe a hit A cache hit (timing / load success) reveals that the target resource was previously loaded in the other context.
- Information disclosure Attacker infers cross-site browsing/cache state (sensitive user information) across what should be a partition boundary.
Impact Assessment
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
| Function | Change | Notes |
|---|---|---|
ifSource/WebCore/inspector/InspectorResourceUtilities.cpp |
modified | |
ifSource/WebCore/loader/archive/cf/LegacyWebArchive.cpp |
modified | |
ifSource/WebCore/loader/cache/CachedResourceLoader.cpp |
modified | |
forSource/WebCore/loader/cache/MemoryCache.cpp |
modified |
Files Changed
LayoutTests/ipc/create-socket-channel-invalid-url-crash.htmlLayoutTests/ipc/invalid-url-network-data-task-crash.htmlSource/WebCore/Modules/websockets/ThreadableWebSocketChannel.cppSource/WebCore/dom/ScriptExecutionContext.cppSource/WebCore/dom/ScriptExecutionContext.hSource/WebCore/html/DOMURL.cppSource/WebCore/inspector/InspectorResourceUtilities.cppSource/WebCore/loader/DocumentLoader.cppSource/WebCore/loader/archive/cf/LegacyWebArchive.cppSource/WebCore/loader/cache/CachedImage.cppSource/WebCore/loader/cache/CachedImage.hSource/WebCore/loader/cache/CachedResource.hSource/WebCore/loader/cache/CachedResourceLoader.cppSource/WebCore/loader/cache/CachedResourceRequest.cppSource/WebCore/loader/cache/CachedResourceRequest.hSource/WebCore/loader/cache/MemoryCache.cppSource/WebCore/page/Page.cppSource/WebCore/platform/network/ResourceRequestBase.cppSource/WebCore/platform/network/ResourceRequestBase.hSource/WebCore/platform/network/cf/ResourceRequest.hSource/WebCore/platform/network/cocoa/ResourceRequestCocoa.mmSource/WebCore/testing/Internals.cppSource/WebCore/workers/service/ServiceWorkerContainer.cppSource/WebCore/workers/service/ServiceWorkerJobData.cppSource/WebCore/workers/service/ServiceWorkerJobData.hSource/WebCore/workers/service/server/SWServer.cppSource/WebCore/xml/XMLHttpRequest.cppSource/WebKit/NetworkProcess/NetworkProcess.cppSource/WebKit/NetworkProcess/NetworkResourceLoader.cppSource/WebKit/NetworkProcess/cache/AsyncRevalidation.cppSource/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cppSource/WebKit/Shared/WebCoreArgumentCoders.serialization.inSource/WebKit/Shared/WebCoreArgumentCodersPlatform.serialization.in
Audit Directions
- Remaining partition assumptionsAudit 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` correctnessSince 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 resourcesRe-examine other manual
CachedResourceinsertion paths (substitute data, archives) for partition keys that bypass the centralized derivation. - Cross-site cache oraclesLook for other caches (preload, font, image-decode) keyed on a domain string rather than the registrable first party.
Patch
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)
Regression Test / PoC
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());
}