Low firefox Logic Error 🔧 Commit mapped

Overview

Low
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impactlow
DescriptionInformation disclosure in the Networking: WebSockets component
ComponentNetworking
Bug ClassLogic Error
Tracker2036591
Fix commitfc5ca5d86492 (firefox) +25/-15
CISA KEVNot listed
CreditedYaqoub Aldurayhim
Disclosed2026-07-21

Changed Functions

FunctionChangeNotes
FailDelay
netwerk/protocol/websocket/WebSocketChannel.cpp
modified
if
netwerk/protocol/websocket/WebSocketChannel.cpp
modified

Files Changed

  • netwerk/protocol/websocket/WebSocketChannel.cpp
diff --git a/netwerk/protocol/websocket/WebSocketChannel.cpp b/netwerk/protocol/websocket/WebSocketChannel.cpp
index 5dd6161947f..618430282b1 100644
--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
@@ -121,8 +121,12 @@ const uint32_t kWSReconnectMaxDelay = 60 * 1000;
 // to same host/path/port.
 class FailDelay {
  public:
-  FailDelay(nsCString address, nsCString path, int32_t port)
-      : mAddress(std::move(address)), mPath(std::move(path)), mPort(port) {
+  FailDelay(nsCString address, nsCString path, int32_t port,
+            nsCString originSuffix)
+      : mAddress(std::move(address)),
+        mPath(std::move(path)),
+        mPort(port),
+        mOriginSuffix(std::move(originSuffix)) {
     mLastFailure = TimeStamp::Now();
     mNextDelay = kWSReconnectInitialBaseDelay +
                  (rand() % kWSReconnectInitialRandomDelay);
@@ -160,6 +164,7 @@ class FailDelay {
   nsCString mAddress;  // IP address (or hostname if using proxy)
   nsCString mPath;
   int32_t mPort;
+  nsCString mOriginSuffix;
 
  private:
   TimeStamp mLastFailure;  // Time of last failed attempt
@@ -190,18 +195,20 @@ class FailDelayManager {
 
   ~FailDelayManager() { MOZ_COUNT_DTOR(FailDelayManager); }
 
-  void Add(nsCString& address, nsCString& path, int32_t port) {
+  void Add(nsCString& address, nsCString& path, int32_t port,
+           nsCString& originSuffix) {
     if (mDelaysDisabled) {
       return;
     }
 
-    mEntries.AppendElement(MakeUnique<FailDelay>(address, path, port));
+    mEntries.AppendElement(
+        MakeUnique<FailDelay>(address, path, port, originSuffix));
   }
 
   // Element returned may not be valid after next main thread event: don't keep
   // pointer to it around
   FailDelay* Lookup(nsCString& address, nsCString& path, int32_t port,
-                    uint32_t* outIndex = nullptr) {
+                    nsCString& originSuffix, uint32_t* outIndex = nullptr) {
     if (mDelaysDisabled) {
       return nullptr;
     }
@@ -214,7 +221,7 @@ class FailDelayManager {
     for (int32_t i = mEntries.Length() - 1; i >= 0; --i) {
       FailDelay* fail = mEntries[i].get();
       if (fail->mAddress.Equals(address) && fail->mPath.Equals(path) &&
-          fail->mPort == port) {
+          fail->mPort == port && fail->mOriginSuffix.Equals(originSuffix)) {
         if (outIndex) *outIndex = i;
         result = fail;
         // break here: removing more entries would mess up *outIndex.
@@ -233,7 +240,8 @@ class FailDelayManager {
   void DelayOrBegin(WebSocketChannel* ws) {
     if (!mDelaysDisabled) {
       uint32_t failIndex = 0;
-      FailDelay* fail = Lookup(ws->mAddress, ws->mPath, ws->mPort, &failIndex);
+      FailDelay* fail = Lookup(ws->mAddress, ws->mPath, ws->mPort,
+                               ws->mOriginSuffix, &failIndex);
 
       if (fail) {
         TimeStamp rightNow = TimeStamp::Now();
@@ -269,14 +277,15 @@ class FailDelayManager {
 
   // Remove() also deletes all expired entries as it iterates: better for
   // battery life than using a periodic timer.
-  void Remove(nsCString& address, nsCString& path, int32_t port) {
+  void Remove(nsCString& address, nsCString& path, int32_t port,
+              nsCString& originSuffix) {
     TimeStamp rightNow = TimeStamp::Now();
 
     // iterate from end, to make deletion indexing easier
     for (int32_t i = mEntries.Length() - 1; i >= 0; --i) {
       FailDelay* entry = mEntries[i].get();
       if ((entry->mAddress.Equals(address) && entry->mPath.Equals(path) &&
-           entry->mPort == port) ||
+           entry->mPort == port && entry->mOriginSuffix.Equals(originSuffix)) ||
           entry->IsExpired(rightNow)) {
         mEntries.RemoveElementAt(i);
       }
@@ -328,8 +337,8 @@ class nsWSAdmissionManager {
     bool hostFound = (sManager->IndexOf(ws->mAddress, ws->mOriginSuffix) >= 0);
 
     uint32_t failIndex = 0;
-    FailDelay* fail = sManager->mFailures.Lookup(ws->mAddress, ws->mPath,
-                                                 ws->mPort, &failIndex);
+    FailDelay* fail = sManager->mFailures.Lookup(
+        ws->mAddress, ws->mPath, ws->mPort, ws->mOriginSuffix, &failIndex);
     bool existingFail = fail != nullptr;
 
     // Always add ourselves to queue, even if we'll connect immediately
@@ -377,7 +386,7 @@ class nsWSAdmissionManager {
 
     // Connection succeeded, so stop keeping track of any previous failures
     sManager->mFailures.Remove(aChannel->mAddress, aChannel->mPath,
-                               aChannel->mPort);
+                               aChannel->mPort, aChannel->mOriginSuffix);
 
     // Check for queued connections to same host.
     // Note: still need to check for failures, since next websocket with same
@@ -398,8 +407,9 @@ class nsWSAdmissionManager {
 
     if (NS_FAILED(aReason)) {
       // Have we seen this failure before?
-      FailDelay* knownFailure = sManager->mFailures.Lookup(
-          aChannel->mAddress, aChannel->mPath, aChannel->mPort);
+      FailDelay* knownFailure =
+          sManager->mFailures.Lookup(aChannel->mAddress, aChannel->mPath,
+                                     aChannel->mPort, aChannel->mOriginSuffix);
       if (knownFailure) {
         if (aReason == NS_ERROR_NOT_CONNECTED) {
           // Don't count close() before connection as a network error
@@ -418,7 +428,7 @@ class nsWSAdmissionManager {
              aChannel->mAddress.get(), aChannel->mPath.get(),
              (int)aChannel->mPort, aChannel));
         sManager->mFailures.Add(aChannel->mAddress, aChannel->mPath,
-                                aChannel->mPort);
+                                aChannel->mPort, aChannel->mOriginSuffix);
       }
     }
 
Loading diff…