Medium firefox Cross Origin 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impactmoderate
DescriptionSame-origin policy bypass in the Networking: Cookies component
ComponentDOM
Bug ClassCross Origin
Tracker2050482
Fix commit606afcd16b12 (firefox) +40/-1
CISA KEVNot listed
Credited5up3rh3i
Disclosed2026-08-18

Changed Functions

FunctionChangeNotes
CookieStoreParent
dom/cookiestore/CookieStoreParent.cpp
modified
for
dom/cookiestore/CookieStoreSubscriptionService.cpp
modified

Files Changed

  • dom/cookiestore/CookieStoreNotifier.cpp
  • dom/cookiestore/CookieStoreParent.cpp
  • dom/cookiestore/CookieStoreSubscriptionService.cpp
diff --git a/dom/cookiestore/CookieStoreNotifier.cpp b/dom/cookiestore/CookieStoreNotifier.cpp
index 2aeac8c2d49..e127ba4b64b 100644
--- a/dom/cookiestore/CookieStoreNotifier.cpp
+++ b/dom/cookiestore/CookieStoreNotifier.cpp
@@ -10,6 +10,7 @@
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/net/Cookie.h"
 #include "mozilla/net/CookieCommons.h"
+#include "nsContentUtils.h"
 #include "nsGlobalWindowInner.h"
 #include "nsICookie.h"
 #include "nsICookieNotification.h"
@@ -49,7 +50,9 @@ already_AddRefed<CookieStoreNotifier> CookieStoreNotifier::Create(
   }
 
   nsCString host;
-  if (NS_WARN_IF(NS_FAILED(principal->GetAsciiHost(host))) || host.IsEmpty()) {
+  if (NS_WARN_IF(NS_FAILED(
+          nsContentUtils::GetHostOrIPv6WithBrackets(principal, host))) ||
+      host.IsEmpty()) {
     return nullptr;
   }
 
diff --git a/dom/cookiestore/CookieStoreParent.cpp b/dom/cookiestore/CookieStoreParent.cpp
index b9a51c2d18f..8620a653f63 100644
--- a/dom/cookiestore/CookieStoreParent.cpp
+++ b/dom/cookiestore/CookieStoreParent.cpp
@@ -24,6 +24,7 @@
 #include "nsICookieManager.h"
 #include "nsICookieService.h"
 #include "nsIEffectiveTLDService.h"
+#include "nsNetUtil.h"
 #include "nsProxyRelease.h"
 
 using namespace mozilla::ipc;
@@ -65,6 +66,16 @@ bool CheckContentProcessSecurity(ThreadsafeContentParentHandle* aParent,
   return cs->ContentProcessHasCookie(aDomain, aOriginAttributes);
 }
 
+bool SubscriptionPrincipalMatchesScope(nsIPrincipal* aPrincipal,
+                                       const nsACString& aScopeURL) {
+  nsCOMPtr<nsIURI> scopeURI;
+  if (NS_WARN_IF(NS_FAILED(NS_NewURI(getter_AddRefs(scopeURI), aScopeURL)))) {
+    return false;
+  }
+
+  return aPrincipal->IsSameOrigin(scopeURI);
+}
+
 }  // namespace
 
 CookieStoreParent::CookieStoreParent() { AssertIsOnBackgroundThread(); }
@@ -218,6 +229,10 @@ mozilla::ipc::IPCResult CookieStoreParent::RecvGetSubscriptionsRequest(
     return IPC_FAIL(this, "principal not allowed for remote type");
   }
 
+  if (!SubscriptionPrincipalMatchesScope(principal, aScopeURL)) {
+    return IPC_FAIL(this, "principal not same-origin with scope");
+  }
+
   InvokeAsync(GetMainThreadSerialEventTarget(), __func__,
               [self = RefPtr(this), aPrincipalInfo, aScopeURL]() {
                 CookieStoreSubscriptionService* service =
@@ -268,6 +283,10 @@ mozilla::ipc::IPCResult CookieStoreParent::RecvSubscribeOrUnsubscribeRequest(
     return IPC_FAIL(this, "principal not allowed for remote type");
   }
 
+  if (!SubscriptionPrincipalMatchesScope(principal, aScopeURL)) {
+    return IPC_FAIL(this, "principal not same-origin with scope");
+  }
+
   InvokeAsync(GetMainThreadSerialEventTarget(), __func__,
               [self = RefPtr(this), aPrincipalInfo, aScopeURL, aSubscriptions,
                aSubscription]() {
diff --git a/dom/cookiestore/CookieStoreSubscriptionService.cpp b/dom/cookiestore/CookieStoreSubscriptionService.cpp
index 004375623f5..2ee66f224ee 100644
--- a/dom/cookiestore/CookieStoreSubscriptionService.cpp
+++ b/dom/cookiestore/CookieStoreSubscriptionService.cpp
@@ -12,6 +12,7 @@
 #include "mozilla/net/Cookie.h"
 #include "mozilla/net/CookieCommons.h"
 #include "nsAppDirectoryServiceDefs.h"
+#include "nsContentUtils.h"
 #include "nsICookieNotification.h"
 
 using namespace mozilla::dom;
@@ -321,6 +322,22 @@ CookieStoreSubscriptionService::Observe(nsISupports* aSubject,
       continue;
     }
 
+    nsCOMPtr<nsIURI> principalURI;
+    rv = NS_NewURI(getter_AddRefs(principalURI), principalInfo.spec());
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      continue;
+    }
+
+    nsAutoCString host;
+    rv = nsContentUtils::GetHostOrIPv6WithBrackets(principalURI, host);
+    if (NS_WARN_IF(NS_FAILED(rv)) || host.IsEmpty()) {
+      continue;
+    }
+
+    if (!CookieCommons::DomainMatches(Cookie::Cast(cookie), host)) {
+      continue;
+    }
+
     for (const CookieSubscription& subscription : data.mSubscriptions) {
       if (subscription.name().isSome() && subscription.name().value() != name) {
         continue;
Loading diff…