← WebKit Silent-Fix Report — 2026-W22

479f2b4542  RELEASE_ASSERT in NetworkConnectionToWebProcess::scheduleResourceLoad() can be abused

severity medium class Bypass confidence 0.60 WebKit NetworkProcess IPC exploitable-grade
Chris Dumez Tue May 26 22:25:28 2026 -0700 full: 479f2b4542deea74b5626f1dfb79451a614963e5 bug report ↗ view on GitHub ↗
Primitive: web process crashes network process via null load identifier
Triage note: A compromised web process could trigger the release assert (network-process crash); MESSAGE_CHECK turns it into graceful IPC rejection.
Contents

The bug at a glance

Medium (denial-of-service / abusable release assert across the IPC trust boundary). OBSERVED: NetworkConnectionToWebProcess::scheduleResourceLoad() guarded the load identifier with RELEASE_ASSERT(identifier). The identifier arrives from the (less-trusted) WebContent process over IPC; a compromised or malicious WebContent process can send a null/zero identifier, which would fire the RELEASE_ASSERT and crash the shared, higher-privileged network process — taking down networking for all web content, not just the misbehaving process. The fix swaps it for MESSAGE_CHECK, which on a failed check rejects the IPC message and terminates the offending WebContent process instead. INFERRED: this is a robustness/anti-abuse fix at a process boundary, not a memory-corruption primitive, so DoS-class medium.

An attacker-controlled IPC field was validated with RELEASE_ASSERT, so a bad value crashed the trusted network process; MESSAGE_CHECK moves the crash to the untrusted sender.

Root cause

In WebKit’s multi-process model the NetworkProcess is a single, comparatively trusted process serving many WebContent processes. NetworkConnectionToWebProcess is the per-WebContent IPC endpoint inside the network process, and scheduleResourceLoad() is invoked in response to a message from that WebContent process carrying NetworkResourceLoadParameters. The message includes loadParameters.identifier, a resource-load identifier chosen by the sender.

The original code did auto identifier = loadParameters.identifier; RELEASE_ASSERT(identifier);. RELEASE_ASSERT aborts the current process unconditionally when its condition is false, in release builds too. Because identifier is fully controlled by the WebContent process, a compromised renderer can simply send a resource-load request with a null (zero) identifier. That would make RELEASE_ASSERT(identifier) fail inside the network process and crash it. Since the network process is shared across all WebContent processes and the browser’s networking, this is a cross-process denial of service: one exploited/compromised renderer can repeatedly kill the network process, disrupting every tab.

The fix replaces RELEASE_ASSERT(identifier) with MESSAGE_CHECK(identifier). MESSAGE_CHECK is the standard WebKit IPC-hardening macro: when the checked condition is false it treats the message as malformed/malicious, and instead of crashing the receiving (network) process it tears down the IPC connection and terminates the sending WebContent process. This keeps the trust boundary correct — a misbehaving sender is punished, and the shared network process stays alive. The adjacent RELEASE_ASSERT(RunLoop::isMain()) is untouched because that reflects an internal invariant not controllable by the sender.

Key code

scheduleResourceLoad — sender-controlled identifier guarded with MESSAGE_CHECK

     auto identifier = loadParameters.identifier;
-    RELEASE_ASSERT(identifier);
+    MESSAGE_CHECK(identifier);
     RELEASE_ASSERT(RunLoop::isMain());
     ASSERT(!m_networkResourceLoaders.contains(*identifier));

Patch walkthrough

  • Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp — In scheduleResourceLoad(), the guard on the sender-supplied load identifier changes from RELEASE_ASSERT(identifier) to MESSAGE_CHECK(identifier). A null identifier from a compromised WebContent process now results in that WebContent process being terminated and the IPC message rejected, rather than the network process aborting. The following RELEASE_ASSERT(RunLoop::isMain()) remains, as thread invariance is not attacker-controlled.

Background

NetworkProcess — A single shared, comparatively trusted WebKit process that performs network loads on behalf of all WebContent processes; crashing it disrupts networking browser-wide.

NetworkConnectionToWebProcess — Per-WebContent IPC endpoint inside the network process; its message handlers receive attacker-influenced parameters from the renderer.

RELEASE_ASSERT — Aborts the current process (including release builds) when the condition is false — appropriate for internal invariants, dangerous when the condition depends on untrusted IPC input.

MESSAGE_CHECK — WebKit IPC-hardening macro that, on a failed check, treats the message as malicious: it rejects the message and terminates the sending (WebContent) process rather than the receiver.

Resource-load identifier — loadParameters.identifier, chosen by the WebContent process to key a load; a null value must be rejected as malformed input, not asserted.

Vulnerability window

  1. Original — scheduleResourceLoad guards the sender-supplied identifier with RELEASE_ASSERT(identifier).
  2. Boundary flaw — identifier is attacker-controllable IPC data, so a null value crashes the trusted network process.
  3. Abuse — A compromised WebContent process sends a resource load with a null identifier, killing the shared network process (DoS across all tabs).
  4. Fix (313945@main) — RELEASE_ASSERT(identifier) becomes MESSAGE_CHECK(identifier), redirecting the fatal outcome to the offending WebContent process.
  5. Branch origin — Originally landed as 305413.509 on the safari-7624 branch (246f60f4724f) before mainline.

Triggering

No test added; this is an IPC-hardening change. Trigger concept: from a compromised/instrumented WebContent process, send the NetworkConnectionToWebProcess::ScheduleResourceLoad IPC message with loadParameters.identifier set to a null/zero optional. Pre-fix, RELEASE_ASSERT(identifier) fires in the network process and crashes it; post-fix, MESSAGE_CHECK rejects the message and terminates the sending WebContent process, leaving the network process running.

Exploitation

  1. Compromise a renderer — Gain code execution in a WebContent process (the assumed threat model for IPC hardening).
  2. Forge the IPC message — Send scheduleResourceLoad with a null loadParameters.identifier, a field the sender fully controls.
  3. Crash the network process (pre-fix) — RELEASE_ASSERT(identifier) aborts the shared network process; repeating it denies networking to every WebContent process — a cross-process DoS.

Detection & hunting

For defenders and SOC / detection engineers:

  • Network process crashes with null identifier
  • MESSAGE_CHECK-driven WebContent terminations

Audit directions

  • RELEASE_ASSERT on IPC-supplied data
  • NetworkResourceLoadParameters validation
  • MESSAGE_CHECK coverage in scheduleResourceLoad path

Before / after

Loading diff…