CVE-2024-44212
Overview
Impact:
Description: Cookies belonging to one origin may be sent to another origin
Researchers: Wojciech Regula of SecuRing (
Key insight. Classifying a web-archive load by the raw URL string (which includes query/fragment/encoding) instead of the filesystem path let an attacker hide or fake the .webarchive suffix, bypassing the ephemeral-store isolation and leaking cookies across origins.
Patch Details
diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp
index a36d0ca506c9..fd0ead8b1a10 100644
--- a/Source/WebKit/UIProcess/WebPageProxy.cpp
+++ b/Source/WebKit/UIProcess/WebPageProxy.cpp
@@ -4674,7 +4674,7 @@ void WebPageProxy::receivedNavigationActionPolicyDecision(WebProcessProxy& proce
if (preferences().loadWebArchiveWithEphemeralStorageEnabled() && navigation && policyAction == PolicyAction::Use && navigationAction->navigationType() != NavigationType::Reload && !isPolicyDataStore) {
bool isSubstituteWebArchive = navigation->substituteData() && MIMETypeRegistry::isWebArchiveMIMEType(navigation->substituteData()->MIMEType);
auto webarchiveURL = isSubstituteWebArchive ? URL { navigation->substituteData()->baseURL } : navigation->currentRequest().url();
- if (isSubstituteWebArchive || (webarchiveURL.protocolIsFile() && webarchiveURL.string().endsWith(".webarchive"_s))) {
+ if (isSubstituteWebArchive || (webarchiveURL.protocolIsFile() && webarchiveURL.fileSystemPath().endsWith(".webarchive"_s))) {
WEBPAGEPROXY_RELEASE_LOG(Loading, "receivedNavigationActionPolicyDecision: Swapping in non-persistent websiteDataStore for web archive.");
if (navigation->targetItem() && navigation->targetItem()->dataStoreForWebArchive())
websiteDataStore = *navigation->targetItem()->dataStoreForWebArchive();
Background
Advisory: Apple Security Advisory
| Attribute | Value |
|---|---|
| CVE | CVE-2024-44212 |
| Bugzilla | 279226 |
| Component | WebKit |
| Bug Class | CrossOrigin |
| Severity | medium |
| Commit | 11494e6772915212… |
| Advisory | Apple Advisory |
Terminology
- Web archive (.webarchive) — A single-file snapshot of a page and its subresources that WebKit can load, with its own baseURL origin.
- Ephemeral / non-persistent data store — A website data store with no on-disk persistence, swapped in for web archive loads to isolate their cookies and storage.
- URL string vs filesystem path — url.string() is the full serialized URL (scheme, path, query, fragment, encoding); url.fileSystemPath() is the decoded local path only.
- Navigation policy decision — The UIProcess step that decides how a navigation proceeds, including which data store backs it.
Root Cause Analysis
WebPageProxy::receivedNavigationActionPolicyDecision decides whether a navigation should be loaded in a swapped-in non-persistent (ephemeral) website data store, which is done for web archives so their content is isolated. The webarchive detection tested webarchiveURL.string().endsWith(".webarchive") — i.e. it matched the suffix against the full URL string, which includes the query and fragment and percent-encoding, not just the file path. A file URL for a genuine .webarchive that carries a query or fragment (e.g. file:///path/x.webarchive?a or ...x.webarchive#a) has a .string() that does NOT end in .webarchive, so the archive was not recognized and the ephemeral-store swap was skipped; the archive then loaded in the normal persistent data store, so cookies associated with the archive’s origin were read from / written to the shared persistent store and could reach another origin. The fix matches against webarchiveURL.fileSystemPath(), the decoded filesystem path with query/fragment stripped, so the .webarchive classification reflects the real file rather than an attacker-manipulable URL string, and the ephemeral-store isolation is applied to exactly the webarchive loads it is meant for. The restored invariant is that ‘is this a .webarchive load’ is decided from the file path, not from a URL string that can be altered without changing the file. This runs in the UIProcess navigation policy path, not the sandboxed WebContent.
Attack Path
1. Host a web archive
Get the victim to open a .webarchive file (local file load or substitute data) that should be isolated in an ephemeral data store.
2. Perturb the URL string
Reference the archive with a URL whose string does not end in ‘.webarchive’ though the file path does — e.g. append a query or fragment (x.webarchive?a / x.webarchive#a).
3. Defeat archive detection
endsWith on url.string() fails to match, so receivedNavigationActionPolicyDecision does not swap in the non-persistent store.
4. Leak cookies across origins
The archive loads in the persistent store, so cookies tied to the archive’s baseURL origin are read/written in the shared store and can be sent to another origin.
Impact Assessment
No memory-safety primitive; this is a privacy/isolation logic bug. Mis-detecting web archives caused the ephemeral-store isolation to be skipped, so cookies belonging to one origin could be sent to another origin. It affects data confidentiality/integrity of cookies and executes in the UIProcess navigation path; there is no path to code execution. Rated medium.
Audit Directions
Other suffix/extension checks on url.string()
grep WebKit/WebCore for .string().endsWith( / .startsWith( / contains( on URLs used for security decisions; prefer fileSystemPath()/path() where a file is meant.
Data-store / storage-partition selection
Audit other branches choosing persistent vs ephemeral stores or storage partitions based on URL shape rather than resolved origin.
webarchive handling
Review all isWebArchiveMIMEType / .webarchive handling for consistent path-based classification across load, save, and policy paths.
Changed Functions
| Function | File | Change | Note |
|---|---|---|---|
WebPageProxy::receivedNavigationActionPolicyDecision |
Source/WebKit/UIProcess/WebPageProxy.cpp |
modified | Detects a web archive with webarchiveURL.fileSystemPath().endsWith(".webarchive") instead of webarchiveURL.string().endsWith(…), so query/fragment/encoding can’t hide or fake the archive suffix and ephemeral-store isolation is applied correctly. |