Medium CVSS 6.5 webkit Bypass 🔧 Commit mapped

Overview

Medium
Severity
6.5
CVSS
No
Exploited ITW
Fixed
Fix Status
DescriptionAn app may be able to read files outside of its sandbox
ComponentWebKit NetworkProcess
Bug ClassBypass
Tracker314867
Fix commit74d0c628ff2d (WebKit/WebKit) +8/-2
CWECWE-284
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N
CISA KEVNot listed
CreditedBrian Carpenter
Disclosed2026-07-27

Background

Sandbox extension
A token passed from the UI process that grants the Network/WebContent process temporary access to a specific file; the normal way local file loads are authorized.
Container temp directory
The app’s private temporary directory; an iOS-family exemption allowed extension-less local loads from here for apps that use fetch/loadHTMLString without passing an extension.
isLocalFileLoadAllowed
The Network-process gate deciding whether a WebContent-initiated local file load is permitted.

Root Cause Analysis

This fixes a sandbox file-read exemption that was too broad in the Network process. NetworkResourceLoader::isLocalFileLoadAllowed contains an iOS-family exemption that allows WebContent-initiated local file loads (via the fetch JS API or -[WKWebView loadHTMLString:baseURL:]) from the app’s container temporary directory, because such loads are not accompanied by a sandbox extension from the UI process.

Before the fix this exemption applied to every app, including MobileSafari, so web content running in Safari could use fetch/loadHTMLString to read local files under the container temp directory that lie outside what the web content should be able to access — reading files outside its sandbox.

The fix adds !WTF::IOSApplication::isMobileSafari() to the condition, so the undocumented temp-directory exemption no longer applies to Safari (it remains only for third-party apps that depend on it), and Safari’s local file loads must go through the normal sandbox-extension path.

The restored invariant is that Safari web content cannot load local files by this extension-less exemption. INFERENCE: the concrete file an attacker reads depends on what lands in the container temp directory; the commit establishes that the exemption previously covered Safari and now excludes it.

Key insight
A compatibility exemption written for third-party apps (which legitimately load local files without a sandbox extension) was scoped too broadly and also covered MobileSafari. Adding !WTF::IOSApplication::isMobileSafari() narrows the exemption to the apps that need it and forces Safari back onto the normal sandbox-extension path.

Attack Path

  1. Run web content in Safari The attacker gets script executing in a MobileSafari WebContent process.
  2. Request a local file in the container temp directory The script uses fetch() (or a loadHTMLString base-URL relative link) to load a file:// URL under the app’s container temporary directory.
  3. Hit the extension-less exemption Pre-patch isLocalFileLoadAllowed returned true for the temp directory even for Safari, so the Network process loaded the file without a sandbox extension.
  4. Read files outside the sandbox Web content obtains the contents of local files it should not have access to (now denied for MobileSafari).

Impact Assessment

A local file read in the context of Safari, escaping the intended file-access sandbox. Web content running in Safari could read files that landed in the app container’s temporary directory but lie outside what that content should reach. Severity depends on what transits the temp directory, but any extension-less local read from web content is a meaningful confidentiality breach.

Changed Functions

FunctionChangeNotes
NetworkResourceLoader::isLocalFileLoadAllowed
Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp
modified Adds !WTF::IOSApplication::isMobileSafari() to the container-temp-directory local-file-load exemption so it no longer applies to Safari, closing the extension-less local file read for Safari web content.

Files Changed

  • Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp

Audit Directions

  • App-specific security exemptions
    Audit other isXApplication()/quirk-style carve-outs in the Network and WebContent sandbox gates; each is a place where a broad default may unintentionally include the browser itself.
  • Extension-less load paths
    Trace every local-file load that proceeds without a sandbox extension and confirm the initiating app is one that genuinely requires the exemption.
diff --git a/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp b/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp
index 91809cdd24f4..ccfe30b53983 100644
--- a/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp
+++ b/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp
@@ -103,6 +103,7 @@
 
 #if PLATFORM(COCOA)
 #include "PathsBlockedForSandboxExtensions.h"
+#include <wtf/cocoa/RuntimeApplicationChecksCocoa.h>
 #endif
 
 #define LOADER_RELEASE_LOG_WITH_THIS(thisPtr, fmt, ...) RELEASE_LOG(Network, "%p - [pageProxyID=%" PRIu64 ", webPageID=%" PRIu64 ", frameID=%" PRIu64 ", resourceID=%" PRIu64 ", isMainResource=%d, destination=%u, isSynchronous=%d] NetworkResourceLoader::" fmt, WTF::getPtr(thisPtr), thisPtr->webPageProxyID().toUInt64(), thisPtr->pageID().toUInt64(), thisPtr->frameID().toUInt64(), thisPtr->coreIdentifier().toUInt64(), thisPtr->isMainResource(), static_cast<unsigned>(thisPtr->m_parameters.options.destination), thisPtr->isSynchronous(), ##__VA_ARGS__)
@@ -396,13 +397,18 @@ bool NetworkResourceLoader::shouldSendResourceLoadMessages() const
 bool NetworkResourceLoader::isLocalFileLoadAllowed(const URL& url)
 {
 #if PLATFORM(IOS_FAMILY)
-    // Some applications are relying on using the fetch JS API to load local files they have created in their temp directory.
+    // Some 3rd party apps are relying on using the fetch JS API or -[WKWebView loadHTMLString:baseURL:] to load local files in their temp directory.
     // In this case, the WebContent process will not provide the Networking process with a sandbox extension to that file, since it does not have access.
     // This is because the load is not initiated from the UI process which would provide an extension, but from JS in the WebContent process.
     // To continue supporting this undocumented feature, we should allow local file loads from that location.
 
+    // FIXME: rdar://177160334
+    // The method -[WKWebView loadHTMLString:baseURL:] can be used to load local files by referring to links relative to the base URL in the HTML string.
+    // When the app is using -[WKWebView loadHTMLString:baseURL:] to load files in the temp directory, we should create a sandbox extension for the base URL.
+    // This can be done in WebPageProxy::loadDataWithNavigationShared. However, this is a larger change, so for now we rely on this exemption.
+
     String directory = connectionToWebProcess().networkProcess().containerTemporaryDirectory();
-    if (!directory.isEmpty() && FileSystem::isAncestor(directory, FileSystem::realPath(url.fileSystemPath()))) {
+    if (!WTF::IOSApplication::isMobileSafari() && !directory.isEmpty() && FileSystem::isAncestor(directory, FileSystem::realPath(url.fileSystemPath()))) {
         RELEASE_LOG(Network, "shouldAllowLocalFileLoad: allowing loads from the temp directory");
         return true;
     }
Loading diff…

Original Bug Report

The reporter's bug is still restricted on the tracker.