CVE-2026-12301
Overview
Background
- `HttpChannelParent`
- the parent-process (privileged) endpoint of the
PHttpChannelIPDL protocol that services HTTP channel requests originating in a content child process. - `PHttpChannel`
- the IPDL-defined message protocol linking a content-process HTTP channel child to its parent actor, over which the removed
SetCookiesmessage was sent. - `CookieServiceParent`
- the parent-process cookie service that actually validates and stores cookies, reachable through the dedicated
PCookieServiceprotocol. - `OriginAttributes`
- the isolation key (containing partition/private-browsing/user-context data) that scopes a cookie to a particular security context.
Root Cause Analysis
The HttpChannelParent::RecvSetCookies handler accepted a child-supplied aBaseDomain, aOriginAttributes, aHost (nsIURI), aIsThirdParty flag, and an array of CookieStruct values and forwarded them straight into cs->SetCookies on the CookieServiceParent it fetched via LoneManagedOrNullAsserts(Manager()->ManagedPCookieServiceParent()). This created a second, redundant cookie-setting entry point alongside the dedicated PCookieService::SetCookies path, but one reached over the per-channel PHttpChannel actor where the BrowsingContext and origin context are derived differently. Because a compromised or malicious content process fully controls the IPC arguments, this alternate path let the child drive cookie storage with attacker-chosen aBaseDomain/aOriginAttributes/aHost that need not correspond to the channel’s real origin, violating the invariant that cookies are only ever set for the security context the parent authoritatively owns.
The fix removes the RecvSetCookies handler, its HttpChannelParent.h declaration, and the SetCookies message from PHttpChannel.ipdl entirely, eliminating the duplicate channel and forcing all cookie writes through the single vetted PCookieService path. Consolidating to one code path removes the divergent, less-guarded surface that the memory-safety/logic bug depended on.
PHttpChannel::SetCookies in addition to the canonical PCookieService::SetCookies — so the fix deletes the redundant HttpChannelParent route and lets only the single validated path remain.Attack Path
- Compromise the content process
An attacker gains code execution in a content/child process, giving them arbitrary control over messages sent on the
PHttpChannelactor. - Craft the SetCookies message
They send
PHttpChannel::SetCookieswith attacker-chosenbaseDomain,attrs(OriginAttributes),host(nsIURI),isThirdParty, andcookiesfields. - Reach the redundant parent handler
HttpChannelParent::RecvSetCookiesreceives the message and resolves theCookieServiceParentviaLoneManagedOrNullAsserts. - Forward into cookie storage
The handler calls
cs->SetCookies(...)with the child-supplied arguments and aBrowsingContexttaken frommBrowserParent, driving cookie writes through the weaker path.
Impact Assessment
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifnetwerk/protocol/http/HttpChannelParent.cpp |
modified |
Files Changed
netwerk/protocol/http/HttpChannelParent.cppnetwerk/protocol/http/HttpChannelParent.hnetwerk/protocol/http/PHttpChannel.ipdl
Audit Directions
- Redundant IPC entry pointsFlag any parent handler that duplicates functionality already provided by a dedicated, more-vetted protocol (here
PCookieService), since the weaker duplicate becomes the attack surface. - Child-controlled security contextScrutinize parent handlers that accept origin-defining inputs such as
baseDomain,OriginAttributes, or annsIURIhost from the child and pass them into storage without re-deriving them authoritatively in the parent. - `LoneManagedOrNullAsserts` forwardingReview handlers that fetch a managed sub-actor and immediately forward raw IPC arguments to it, confirming the parent independently validates the request against the channel’s true origin.
Patch
diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp
index b1ed09f08fb..82a349e0e42 100644
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -1064,25 +1064,6 @@ mozilla::ipc::IPCResult HttpChannelParent::RecvRemoveCorsPreflightCacheEntry(
return IPC_OK();
}
-mozilla::ipc::IPCResult HttpChannelParent::RecvSetCookies(
- const nsACString& aBaseDomain, const OriginAttributes& aOriginAttributes,
- nsIURI* aHost, const bool& aIsThirdParty,
- nsTArray<CookieStruct>&& aCookies) {
- net::PCookieServiceParent* csParent =
- LoneManagedOrNullAsserts(Manager()->ManagedPCookieServiceParent());
- NS_ENSURE_TRUE(csParent, IPC_OK());
-
- auto* cs = static_cast<net::CookieServiceParent*>(csParent);
-
- BrowsingContext* browsingContext = nullptr;
- if (mBrowserParent) {
- browsingContext = mBrowserParent->GetBrowsingContext();
- }
-
- return cs->SetCookies(nsCString(aBaseDomain), aOriginAttributes, aHost,
- aIsThirdParty, aCookies, browsingContext);
-}
-
//-----------------------------------------------------------------------------
// HttpChannelParent::nsIRequestObserver
//-----------------------------------------------------------------------------
diff --git a/netwerk/protocol/http/HttpChannelParent.h b/netwerk/protocol/http/HttpChannelParent.h
index 55aa41979c6..0870b5d29b1 100644
--- a/netwerk/protocol/http/HttpChannelParent.h
+++ b/netwerk/protocol/http/HttpChannelParent.h
@@ -195,10 +195,6 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
virtual mozilla::ipc::IPCResult RecvRemoveCorsPreflightCacheEntry(
nsIURI* uri, const mozilla::ipc::PrincipalInfo& requestingPrincipal,
const OriginAttributes& originAttributes) override;
- virtual mozilla::ipc::IPCResult RecvSetCookies(
- const nsACString& aBaseDomain, const OriginAttributes& aOriginAttributes,
- nsIURI* aHost, const bool& aIsThirdParty,
- nsTArray<CookieStruct>&& aCookies) override;
virtual mozilla::ipc::IPCResult RecvBytesRead(const int32_t& aCount) override;
virtual mozilla::ipc::IPCResult RecvOpenOriginalCacheInputStream() override;
virtual void ActorDestroy(ActorDestroyReason why) override;
diff --git a/netwerk/protocol/http/PHttpChannel.ipdl b/netwerk/protocol/http/PHttpChannel.ipdl
index 35e928f14a1..e1965ef892d 100644
--- a/netwerk/protocol/http/PHttpChannel.ipdl
+++ b/netwerk/protocol/http/PHttpChannel.ipdl
@@ -59,15 +59,6 @@ parent:
PrincipalInfo requestingPrincipal,
OriginAttributes originAttributes);
- // Send cookies to the parent for a given channel. Compared to PCookieService
- // SetCookies this method allows the parent to determine which BrowsingContext
- // the request was sent for.
- async SetCookies(nsCString baseDomain,
- OriginAttributes attrs,
- nullable nsIURI host,
- bool isThirdParty,
- CookieStruct[] cookies);
-
// After receiving this message, the parent calls SendDeleteSelf, and makes
// sure not to send any more messages after that.
async DeletingChannel();