← WebKit Silent-Fix Report — 2026-W22

fb75caed1b  setRawCookie: cookie.domain unvalidated + commentURL crashes NetworkProcess

severity high class CrossOrigin confidence 0.80 WebKit NetworkProcess (cookies) exploitable-grade
Chris Dumez Fri May 29 14:12:32 2026 -0700 full: fb75caed1b659f4869879706eac63a50dc0225b4 bug report ↗ view on GitHub ↗
Primitive: unvalidated cookie domain from web process; cross-origin cookie set / NetworkProcess crash
Triage note: Adds MESSAGE_CHECKs so a compromised web process can't set cookies for arbitrary domains or crash NetworkProcess.
Contents

The bug at a glance

A compromised or malicious web process could call the NetworkProcess IPC endpoint setRawCookie with an attacker-chosen cookie.domain and url that do not correspond to the firstParty, letting it set cookies for arbitrary domains — a cross-origin cookie injection / session-fixation primitive that undermines origin isolation. Separately, a malformed cookie could throw during NSHTTPCookie creation outside the BLOCK_OBJC_EXCEPTIONS scope and crash the privileged NetworkProcess. Setting cookies for arbitrary domains from a sandbox-escaped renderer is a serious cross-origin/integrity break, warranting high.

setRawCookie trusted the web process’s Cookie struct: it validated firstParty access but never checked that cookie.domain or the target url actually belong to firstParty, so a compromised web process could inject cookies for any domain; and createNSHTTPCookie() sat just outside BEGIN_BLOCK_OBJC_EXCEPTIONS so a throwing (malformed) cookie crashed NetworkProcess.

Root cause

NetworkConnectionToWebProcess::setRawCookie is an IPC handler exposed to the web content process. The web process supplies firstParty, url, and a WebCore::Cookie struct. The pre-patch code only performed allowsFirstPartyForCookies(m_webProcessIdentifier, firstParty) and a MESSAGE_CHECK that the result was not Terminate. It then proceeded to store the cookie. Critically, nothing tied the cookie’s own domain (cookie.domain) or the request url to firstParty. In WebKit’s model the NetworkProcess is the trust boundary: a compromised renderer (post sandbox-escape, or a bug that lets it forge IPC) can send any values. By supplying a cookie whose domain is victim.com while firstParty is an origin it legitimately controls, the web process could set cookies scoped to a domain it has no right to — cross-origin cookie injection enabling session fixation, CSRF-token planting, or auth confusion against arbitrary sites.

The fix adds two MESSAGE_CHECKs. MESSAGE_CHECK(RegistrableDomain::uncheckedCreateFromHost(cookie.domain).matches(firstParty)); ensures the cookie’s declared domain reduces to the same registrable domain (eTLD+1) as firstParty. MESSAGE_CHECK(RegistrableDomain(url).matches(firstParty)); ensures the URL the cookie is being set for is also same-registrable-domain as firstParty. MESSAGE_CHECK in the NetworkProcess kills the offending web process connection on failure, so a renderer that lies about domain/url is terminated rather than honored. Together these enforce that a web process can only set raw cookies consistent with a first party it is authorized for.

The second half addresses a crash. NetworkStorageSession::setCookies builds NSHTTPCookie objects via cookie.createNSHTTPCookie() inside a createNSArray lambda. Cocoa’s +[NSHTTPCookie cookieWithProperties:] can raise an Objective-C exception for malformed inputs (for instance a bad commentURL or other property derived from attacker-controlled cookie fields). Previously BEGIN_BLOCK_OBJC_EXCEPTIONS was placed after the createNSArray call, so an exception thrown during cookie creation was not caught by the BLOCK_OBJC_EXCEPTIONS handler and propagated as an uncaught ObjC exception, crashing the NetworkProcess. The patch moves BEGIN_BLOCK_OBJC_EXCEPTIONS above the createNSArray call so the entire createNSHTTPCookie path is inside the guarded region and the exception is converted into a safe no-op instead of a process abort.

Key code

NetworkConnectionToWebProcess.cpp: setRawCookie validates domain and url against firstParty

    auto allowCookieAccess = m_networkProcess->allowsFirstPartyForCookies(m_webProcessIdentifier, firstParty);
    MESSAGE_CHECK(allowCookieAccess != NetworkProcess::AllowCookieAccess::Terminate);
    MESSAGE_CHECK(RegistrableDomain::uncheckedCreateFromHost(cookie.domain).matches(firstParty));
    MESSAGE_CHECK(RegistrableDomain(url).matches(firstParty));
    if (allowCookieAccess != NetworkProcess::AllowCookieAccess::Allow)
        return;

Patch walkthrough

  • Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp — In setRawCookie, after the existing allowCookieAccess check, two MESSAGE_CHECKs are added: RegistrableDomain::uncheckedCreateFromHost(cookie.domain).matches(firstParty) and RegistrableDomain(url).matches(firstParty). These validate that the cookie’s domain and the target URL belong to the same registrable domain as firstParty; a mismatch terminates the sending web process instead of setting a cross-origin cookie.
  • Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm — In NetworkStorageSession::setCookies, BEGIN_BLOCK_OBJC_EXCEPTIONS is moved to before the createNSArray call that invokes cookie.createNSHTTPCookie(), so an Objective-C exception raised while constructing NSHTTPCookie from malformed cookie fields is caught and neutralized rather than crashing NetworkProcess.

Background

setRawCookie IPC — NetworkConnectionToWebProcess::setRawCookie is a NetworkProcess IPC endpoint the web process calls to set a cookie directly, bypassing the usual Set-Cookie header path; it must not trust caller-supplied fields.

MESSAGE_CHECK — WebKit IPC macro that validates an assertion on a message; on failure it terminates the offending connection/web process, treating the violation as a hostile/compromised renderer.

RegistrableDomain::matches — Compares two origins/URLs at the registrable-domain (eTLD+1) level using the public suffix list, the standard WebKit unit for cookie/site scoping decisions.

firstParty vs cookie.domain — firstParty is the top-level site the web process is authorized for; cookie.domain is the domain the cookie would be scoped to. They must agree, or a renderer could scope cookies to sites it does not control.

BLOCK_OBJC_EXCEPTIONS — WebKit macro pair converting Objective-C exceptions into safe control flow. Cocoa cookie/URL APIs can raise on malformed input; code that may throw must sit inside BEGIN/END_BLOCK_OBJC_EXCEPTIONS.

Vulnerability window

  1. Compromise — An attacker gains code execution or IPC-forging ability in a web content process.
  2. Forge — It calls setRawCookie with a firstParty it is authorized for but a cookie.domain (and url) belonging to a victim site.
  3. Pre-fix accept — NetworkProcess only checked firstParty access and stored the cross-origin cookie, injecting attacker cookies for the victim domain.
  4. Alt: crash — Alternatively it supplies a malformed cookie so createNSHTTPCookie throws outside BLOCK_OBJC_EXCEPTIONS, aborting NetworkProcess.
  5. Post-fix — MESSAGE_CHECKs reject the domain/url mismatch and terminate the renderer; the widened exception block neutralizes the throw.

Exploitation

  1. Sandbox escape — Achieve control of a web content process so IPC messages can be forged with arbitrary Cookie fields.
  2. Cross-origin injection — Send setRawCookie with victim cookie.domain/url to plant session-fixation or CSRF cookies for arbitrary sites the renderer never navigated to.
  3. Auth confusion — Use injected cookies to fix a victim’s session, bypass CSRF tokens, or poison SSO state on high-value origins.
  4. DoS variant — Alternatively feed malformed cookies to crash the shared NetworkProcess, disrupting all browsing (denial of service).

Detection & hunting

For defenders and SOC / detection engineers:

  • MESSAGE_CHECK terminations
  • Domain/firstParty mismatch
  • ObjC exception aborts

Audit directions

  • Renderer-supplied cookie fields
  • Exception scoping
  • First-party gating
  • In-memory cookie store

Before / after

Loading diff…