Medium firefox Logic Error 🔧 Commit mapped

Overview

Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Impactmoderate
DescriptionMemory safety bug fixed in Firefox 152
ComponentNetworking
Bug ClassLogic Error
Tracker2015647
Fix commit87fbf4054f71 (firefox) +0/-32
CISA KEVNot listed
CreditedRichard Belisle
Disclosed2026-06-16

Background

`HttpChannelParent`
the parent-process (privileged) endpoint of the PHttpChannel IPDL 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 SetCookies message was sent.
`CookieServiceParent`
the parent-process cookie service that actually validates and stores cookies, reachable through the dedicated PCookieService protocol.
`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.

Key insight
The core mistake was maintaining two independent IPC routes for setting cookies — a permissive per-channel 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

  1. Compromise the content process An attacker gains code execution in a content/child process, giving them arbitrary control over messages sent on the PHttpChannel actor.
  2. Craft the SetCookies message They send PHttpChannel::SetCookies with attacker-chosen baseDomain, attrs (OriginAttributes), host (nsIURI), isThirdParty, and cookies fields.
  3. Reach the redundant parent handler HttpChannelParent::RecvSetCookies receives the message and resolves the CookieServiceParent via LoneManagedOrNullAsserts.
  4. Forward into cookie storage The handler calls cs->SetCookies(...) with the child-supplied arguments and a BrowsingContext taken from mBrowserParent, driving cookie writes through the weaker path.

Impact Assessment

An attacker who already controls a content process gains an additional, less-guarded means to have the privileged parent write cookies with child-influenced domain and origin-attribute values, undermining cookie/origin isolation. This occurs in the parent (privileged networking) process at the behest of a compromised child, so the precondition is prior content-process compromise rather than a purely remote drive-by. The listed impact is moderate and the flaw is a logic error in the networking component.

Changed Functions

FunctionChangeNotes
if
netwerk/protocol/http/HttpChannelParent.cpp
modified

Files Changed

  • netwerk/protocol/http/HttpChannelParent.cpp
  • netwerk/protocol/http/HttpChannelParent.h
  • netwerk/protocol/http/PHttpChannel.ipdl

Audit Directions

  • Redundant IPC entry points
    Flag 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 context
    Scrutinize parent handlers that accept origin-defining inputs such as baseDomain, OriginAttributes, or an nsIURI host from the child and pass them into storage without re-deriving them authoritatively in the parent.
  • `LoneManagedOrNullAsserts` forwarding
    Review 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.
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();
Loading diff…