Low firefox Logic Error 🔧 Commit mapped

Overview

Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Impactlow
DescriptionPrivilege escalation in the Session Restore component
ComponentToolkit
Bug ClassLogic Error
Tracker2054670
Fix commit6087fa3421ed (firefox) +23/-2
CISA KEVNot listed
CreditedMozilla
Disclosed2026-09-15

Changed Functions

FunctionChangeNotes
if
toolkit/components/sessionstore/SessionStoreParent.cpp
modified

Files Changed

  • toolkit/components/sessionstore/SessionStoreParent.cpp
  • toolkit/components/sessionstore/SessionStoreParent.h
diff --git a/toolkit/components/sessionstore/SessionStoreParent.cpp b/toolkit/components/sessionstore/SessionStoreParent.cpp
index 0a805a4bd16..6e56c8d4e71 100644
--- a/toolkit/components/sessionstore/SessionStoreParent.cpp
+++ b/toolkit/components/sessionstore/SessionStoreParent.cpp
@@ -11,6 +11,7 @@
 #include "mozilla/dom/BrowserSessionStore.h"
 #include "mozilla/dom/BrowserSessionStoreBinding.h"
 #include "mozilla/dom/BrowsingContext.h"
+#include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/InProcessChild.h"
 #include "mozilla/dom/InProcessParent.h"
 #include "mozilla/dom/SessionStoreChild.h"
@@ -190,6 +191,24 @@ mozilla::ipc::IPCResult SessionStoreParent::RecvSessionStoreUpdate(
   return IPC_OK();
 }
 
+bool SessionStoreParent::IsAllowedUpdateTarget(
+    CanonicalBrowsingContext* aBrowsingContext) {
+  // Incremental updates must only carry data for in-process documents of the
+  // process the SessionStoreChild actor lives in, so the target context must
+  // be owned by the sending process and belong to this actor's frame tree.
+  if (InProcessParent::ChildActorFor(this)) {
+    return true;
+  }
+
+  if (!mBrowsingContext || aBrowsingContext->Top() != mBrowsingContext->Top()) {
+    return false;
+  }
+
+  auto* browserParent = static_cast<BrowserParent*>(Manager());
+  return aBrowsingContext->IsOwnedByProcess(
+      browserParent->Manager()->ChildID());
+}
+
 mozilla::ipc::IPCResult SessionStoreParent::RecvIncrementalSessionStoreUpdate(
     const MaybeDiscarded<BrowsingContext>& aBrowsingContext,
     const Maybe<FormData>& aFormData, const Maybe<nsPoint>& aScrollPosition,
@@ -204,7 +223,7 @@ mozilla::ipc::IPCResult SessionStoreParent::RecvIncrementalSessionStoreUpdate(
     } else {
       bc = aBrowsingContext.GetMaybeDiscarded()->Canonical();
     }
-    if (!bc) {
+    if (!bc || !IsAllowedUpdateTarget(bc)) {
       return IPC_OK();
     }
     if (aFormData.isSome()) {
@@ -232,7 +251,7 @@ mozilla::ipc::IPCResult SessionStoreParent::RecvResetSessionStore(
     } else {
       bc = aBrowsingContext.GetMaybeDiscarded()->Canonical();
     }
-    if (!bc) {
+    if (!bc || !IsAllowedUpdateTarget(bc)) {
       return IPC_OK();
     }
     mSessionStore->RemoveSessionStore(bc);
diff --git a/toolkit/components/sessionstore/SessionStoreParent.h b/toolkit/components/sessionstore/SessionStoreParent.h
index 51651f7f0b8..05912958672 100644
--- a/toolkit/components/sessionstore/SessionStoreParent.h
+++ b/toolkit/components/sessionstore/SessionStoreParent.h
@@ -63,6 +63,8 @@ class SessionStoreParent final : public PSessionStoreParent {
  private:
   ~SessionStoreParent() = default;
 
+  bool IsAllowedUpdateTarget(CanonicalBrowsingContext* aBrowsingContext);
+
   already_AddRefed<SessionStoreParent::FlushTabStatePromise>
   FlushSessionStore();
 
Loading diff…