[1] LoadImageForDecoding scheme and cookie-access validation
The decode endpoint that checked a URL was valid — and nothing else.
Rated High because the pre-fix endpoint accepted an attacker-controlled ResourceRequest from WebContent and validated only url.isValid(), letting a compromised renderer reach a file:// load and assert an arbitrary cookie first-party through the NetworkProcess; the escalation to actual local-file disclosure and cross-origin credentialed reads depends on downstream loader behavior the diff does not show, but the fix installs exactly the scheme and cookie-authorization checks that path requires.
LoadImageForDecoding accepted arbitrary ResourceRequest fields with only a url.isValid() check. This allowed file:// reads of NetworkProcess-sandbox files and credentialed cross-origin body reads via a spoofed firstPartyForCookies. The URL is now restricted to HTTP(S) and allowsFirstPartyForCookies is enforced, matching every other cookie-touching IPC entry point.
Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
Source/WebKit/UIProcess/WebPageProxy.cpp
LayoutTests/ipc/load-image-for-decoding-file-url.html
Patch Details
On the NetworkProcess side, NetworkConnectionToWebProcess::loadImageForDecoding tightens its existing MESSAGE_CHECK_COMPLETION(url.isValid(), ...) to also require url.protocolIsInHTTPFamily(), and adds a second MESSAGE_CHECK_COMPLETION requiring m_networkProcess->allowsFirstPartyForCookies(m_webProcessIdentifier, request.firstPartyForCookies()) == NetworkProcess::AllowCookieAccess::Allow. On the UIProcess side, the WebPageProxy::loadAndDecodeImage early-return guard gains || !request.url().protocolIsInHTTPFamily(). The regression test hand-crafts a ResourceRequest with a file:///private/etc/hosts URL through the IPC testing API and asserts the message is now rejected on protocolIsInHTTPFamily.
Trusting attacker-controlled ResourceRequest fields at an IPC boundary without enforcing scheme and cookie-access authorization on the sending process.
Background
The NetworkProcess is reachable from WebContent only through IPC endpoints such as loadImageForDecoding, the privileged endpoint that fetches and decodes images on behalf of the sandboxed WebContent process. A ResourceRequest is a fully serializable bundle of load parameters (URL, firstPartyForCookies, method, headers, cookie policy) that the WebContent process constructs and sends over IPC. MESSAGE_CHECK and its completion variant validate an assertion on an incoming message; on failure they terminate or flag the connection rather than proceeding, so they are the standard authorization gate for messages arriving from a less-privileged process. protocolIsInHTTPFamily() is a predicate that is true only for http/https URLs. firstPartyForCookies is the URL used as the first-party/top-site context when deciding which cookies to attach, and allowsFirstPartyForCookies(processID, url) is the NetworkProcess policy check that confirms a given web process is permitted to use a given URL as that first party. The IPC testing API used by the regression test lets a page synthesize raw IPC messages, modeling a compromised WebContent process.
Analysis
This is an IPC input-validation / access-control bypass (a confused-deputy), not a memory-safety bug. Before the fix, loadImageForDecoding accepted an entirely attacker-controlled ResourceRequest and validated only url.isValid(). Two invariants were missing. First, the request URL was not restricted to the HTTP(S) family, so a file:// URL passed validation and was handed toward the network session for loading. Second, request.firstPartyForCookies() was never checked against allowsFirstPartyForCookies, so the caller could supply an arbitrary first-party URL that the loader would trust when deciding cookie attachment. The NetworkProcess acted on request fields it trusted without re-deriving or re-authorizing them against the sending process's identity.
The exploit direction follows the regression test. From a compromised WebContent process, serialize a ResourceRequest whose m_url is file:///path/to/target and send NetworkConnectionToWebProcess_LoadImageForDecoding; pre-fix, url.isValid() passes and the scheme is not rejected at the entry point, so the request would proceed to the network session. Alternatively, set an http(s) m_url but supply an m_firstPartyForCookies for a victim origin, which pre-fix would be trusted since allowsFirstPartyForCookies was not consulted. Whether these fields then cause the local file to be read and returned as image bytes, or the victim's cookies to be attached and the body returned, depends on the loader path not shown in this diff. This is a second-stage bug: it is not reachable from unprivileged web content alone, and it does not itself grant code execution in the NetworkProcess.
This vulnerability weakens the WebContent/NetworkProcess IPC trust boundary and the cookie first-party authorization model. The security model assumes a compromised WebContent process cannot direct the NetworkProcess to load arbitrary-scheme URLs or assert an arbitrary cookie first-party; before the fix loadImageForDecoding re-emitted attacker-supplied request fields without those authorizations. An attacker who has already achieved code execution in WebContent could plausibly reach a file:// load through the NetworkProcess and could supply a spoofed firstPartyForCookies; if those fields flow to the loader as they appear to, this amounts to a local file-disclosure and cross-origin credentialed data-read primitive.
The recurring lesson: IPC endpoints that accept a full ResourceRequest and forward it to a loader are inherently confused-deputy prone. Any field the caller controls (URL scheme, firstPartyForCookies, cookie policy) must be re-authorized against the sender's identity, because the NetworkProcess's ambient authority exceeds the sender's. A url.isValid()-only gate validates syntax but not authority.
Note: The downstream loading and cookie-attachment consequences are inferred from the field names and the shape of the checks the fix adds; the network-session code that consumes these fields is not part of this diff. The entry-point validation gap itself is directly visible.
Audit directions
- NetworkProcess IPC handlers that accept a full
WebCore::ResourceRequestand forward it to a loader, validating onlyurl.isValid(). Audit every such handler for a missingprotocolIsInHTTPFamily()/scheme restriction and a missingallowsFirstPartyForCookiescheck. GrepSource/WebKit/NetworkProcessforMESSAGE_CHECK*(url.isValid()and for methods takingWebCore::ResourceRequest&&, then compare each against the set that already callallowsFirstPartyForCookies. - Confused-deputy via caller-supplied firstPartyForCookies. Verify that any privileged code path attaching cookies to a request derives or authorizes
firstPartyForCookiesrather than trusting the IPC-supplied value. Start by cross-referencing all callers ofallowsFirstPartyForCookiesinNetworkConnectionToWebProcess.cppagainst every loader entry point that readsrequest.firstPartyForCookies(). - Scheme-based reachability where
file://or other non-HTTP schemes reach a process with broader authority than the sender. Audit UIProcess/NetworkProcess entry points that load a caller-provided URL (image decode, prefetch, preconnect, data tasks) to confirm each restricts scheme before dispatch; grep forprotocolIsInHTTPFamilyusage gaps acrossWebPageProxy.cppandNetworkConnectionToWebProcess.cpploader methods. - Verify parity between the UIProcess mirror
WebPageProxy::loadAndDecodeImageand the NetworkProcess handler: the diff shows the UIProcess side received only the scheme check, not an explicit cookie authorization check. Confirm the cookie authorization is genuinely unreachable or unnecessary on that path, or add it.