High firefox Sandbox Escape 🔧 Commit mapped

Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionSandbox escape in the DOM: Workers component
ComponentDOM
Bug ClassSandbox Escape
Tracker2039873
Fix commit6e310738d31a (firefox) +39/-43
CISA KEVNot listed
CreditedQuy Pham
Disclosed2026-06-16

Changed Functions

FunctionChangeNotes
if
dom/workers/remoteworkers/RemoteWorkerManager.cpp
modified
GetOrCreateWorkerManagerRunnable
dom/workers/sharedworkers/SharedWorkerService.cpp
modified
Run
dom/workers/sharedworkers/SharedWorkerService.cpp
modified

Files Changed

  • dom/serviceworkers/ServiceWorkerPrivate.cpp
  • dom/workers/remoteworkers/RemoteWorkerManager.cpp
  • dom/workers/remoteworkers/RemoteWorkerManager.h
  • dom/workers/sharedworkers/SharedWorker.cpp
  • dom/workers/sharedworkers/SharedWorkerService.cpp
  • dom/workers/sharedworkers/SharedWorkerService.h
diff --git a/dom/serviceworkers/ServiceWorkerPrivate.cpp b/dom/serviceworkers/ServiceWorkerPrivate.cpp
index eb1948f0005..5bda51baf72 100644
--- a/dom/serviceworkers/ServiceWorkerPrivate.cpp
+++ b/dom/serviceworkers/ServiceWorkerPrivate.cpp
@@ -714,7 +714,8 @@ nsresult ServiceWorkerPrivate::Initialize() {
   }
 
   auto remoteType = RemoteWorkerManager::GetRemoteType(
-      principal, WorkerKind::WorkerKindService);
+      principal, WorkerKind::WorkerKindService,
+      SharedWebRemoteType(principal->OriginAttributesRef()));
   if (NS_WARN_IF(remoteType.isErr())) {
     return remoteType.unwrapErr();
   }
diff --git a/dom/workers/remoteworkers/RemoteWorkerManager.cpp b/dom/workers/remoteworkers/RemoteWorkerManager.cpp
index 781c1330e73..24467b59e35 100644
--- a/dom/workers/remoteworkers/RemoteWorkerManager.cpp
+++ b/dom/workers/remoteworkers/RemoteWorkerManager.cpp
@@ -120,7 +120,8 @@ bool RemoteWorkerManager::MatchRemoteType(const nsACString& processRemoteType,
 
 // static
 Result<nsCString, nsresult> RemoteWorkerManager::GetRemoteType(
-    const nsCOMPtr<nsIPrincipal>& aPrincipal, WorkerKind aWorkerKind) {
+    const nsCOMPtr<nsIPrincipal>& aPrincipal, WorkerKind aWorkerKind,
+    const nsACString& aCurrentRemoteType) {
   AssertIsOnMainThread();
 
   MOZ_ASSERT_IF(aWorkerKind == WorkerKind::WorkerKindService,
@@ -133,20 +134,8 @@ Result<nsCString, nsresult> RemoteWorkerManager::GetRemoteType(
     return NOT_REMOTE_TYPE;
   }
 
-  nsCString preferredRemoteType =
-      SharedWebRemoteType(aPrincipal->OriginAttributesRef());
-  if (aWorkerKind == WorkerKind::WorkerKindShared) {
-    if (auto* contentChild = ContentChild::GetSingleton()) {
-      // For a shared worker set the preferred remote type to the content
-      // child process remote type.
-      preferredRemoteType = contentChild->GetRemoteType();
-    } else if (aPrincipal->IsSystemPrincipal()) {
-      preferredRemoteType = NOT_REMOTE_TYPE;
-    }
-  }
-
   auto result = IsolationOptionsForWorker(
-      aPrincipal, aWorkerKind, preferredRemoteType, FissionAutostart());
+      aPrincipal, aWorkerKind, aCurrentRemoteType, FissionAutostart());
   if (NS_WARN_IF(result.isErr())) {
     LOG(("GetRemoteType Abort: IsolationOptionsForWorker failed"));
     return Err(NS_ERROR_DOM_ABORT_ERR);
@@ -161,7 +150,7 @@ Result<nsCString, nsresult> RemoteWorkerManager::GetRemoteType(
         ("GetRemoteType workerType=%s, principal=%s, "
          "preferredRemoteType=%s, selectedRemoteType=%s",
          aWorkerKind == WorkerKind::WorkerKindService ? "service" : "shared",
-         principalOrigin.get(), preferredRemoteType.get(),
+         principalOrigin.get(), PromiseFlatCString(aCurrentRemoteType).get(),
          options.mRemoteType.get()));
   }
 
diff --git a/dom/workers/remoteworkers/RemoteWorkerManager.h b/dom/workers/remoteworkers/RemoteWorkerManager.h
index 1fb5debdcda..d61e120ab15 100644
--- a/dom/workers/remoteworkers/RemoteWorkerManager.h
+++ b/dom/workers/remoteworkers/RemoteWorkerManager.h
@@ -46,7 +46,8 @@ class RemoteWorkerManager final {
    * launched.
    */
   static Result<nsCString, nsresult> GetRemoteType(
-      const nsCOMPtr<nsIPrincipal>& aPrincipal, WorkerKind aWorkerKind);
+      const nsCOMPtr<nsIPrincipal>& aPrincipal, WorkerKind aWorkerKind,
+      const nsACString& aCurrentRemoteType);
 
   static bool HasExtensionPrincipal(const RemoteWorkerData& aData);
 
diff --git a/dom/workers/sharedworkers/SharedWorker.cpp b/dom/workers/sharedworkers/SharedWorker.cpp
index a74d9258b77..5ea65c62e66 100644
--- a/dom/workers/sharedworkers/SharedWorker.cpp
+++ b/dom/workers/sharedworkers/SharedWorker.cpp
@@ -250,13 +250,6 @@ already_AddRefed<SharedWorker> SharedWorker::Constructor(
   MOZ_ASSERT(loadInfo.mCookieJarSettings);
   net::CookieJarSettings::Cast(loadInfo.mCookieJarSettings)->Serialize(cjsData);
 
-  auto remoteType = RemoteWorkerManager::GetRemoteType(
-      loadInfo.mPrincipal, WorkerKind::WorkerKindShared);
-  if (NS_WARN_IF(remoteType.isErr())) {
-    aRv.Throw(remoteType.unwrapErr());
-    return nullptr;
-  }
-
   Maybe<RFPTargetSet> overriddenFingerprintingSettingsArg;
   if (loadInfo.mOverriddenFingerprintingSettings.isSome()) {
     overriddenFingerprintingSettingsArg.emplace(
@@ -273,7 +266,7 @@ already_AddRefed<SharedWorker> SharedWorker::Constructor(
       loadInfo.mIsOn3PCBExceptionList,
       OriginTrials::FromWindow(nsGlobalWindowInner::Cast(window)),
       void_t() /* OptionalServiceWorkerData */, agentClusterId,
-      remoteType.unwrap());
+      DEFAULT_REMOTE_TYPE /* ignored */);
 
   PSharedWorkerChild* pActor = actorChild->SendPSharedWorkerConstructor(
       remoteWorkerData, loadInfo.mWindowID, portIdentifier.release());
diff --git a/dom/workers/sharedworkers/SharedWorkerService.cpp b/dom/workers/sharedworkers/SharedWorkerService.cpp
index 4d536ea9cf2..6e2a874df4e 100644
--- a/dom/workers/sharedworkers/SharedWorkerService.cpp
+++ b/dom/workers/sharedworkers/SharedWorkerService.cpp
@@ -8,6 +8,7 @@
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/SchedulerGroup.h"
 #include "mozilla/StaticMutex.h"
+#include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/MessagePort.h"
 #include "mozilla/dom/RemoteWorkerManager.h"  // RemoteWorkerManager::GetRemoteType
 #include "mozilla/dom/RemoteWorkerTypes.h"
@@ -31,14 +32,15 @@ StaticRefPtr<SharedWorkerService> sSharedWorkerService;
 
 class GetOrCreateWorkerManagerRunnable final : public Runnable {
  public:
-  GetOrCreateWorkerManagerRunnable(SharedWorkerService* aService,
-                                   SharedWorkerParent* aActor,
-                                   const RemoteWorkerData& aData,
-                                   uint64_t aWindowID,
-                                   const MessagePortIdentifier& aPortIdentifier)
+  GetOrCreateWorkerManagerRunnable(
+      SharedWorkerService* aService,
+      ThreadsafeContentParentHandle* aContentParentHandle,
+      SharedWorkerParent* aActor, const RemoteWorkerData& aData,
+      uint64_t aWindowID, const MessagePortIdentifier& aPortIdentifier)
       : Runnable("GetOrCreateWorkerManagerRunnable"),
         mBackgroundEventTarget(GetCurrentSerialEventTarget()),
         mService(aService),
+        mContentParentHandle(aContentParentHandle),
         mActor(aActor),
         mData(aData),
         mWindowID(aWindowID),
@@ -47,7 +49,8 @@ class GetOrCreateWorkerManagerRunnable final : public Runnable {
   NS_IMETHOD
   Run() {
     mService->GetOrCreateWorkerManagerOnMainThread(
-        mBackgroundEventTarget, mActor, mData, mWindowID, mPortIdentifier);
+        mBackgroundEventTarget, mContentParentHandle, mActor, mData, mWindowID,
+        mPortIdentifier);
 
     return NS_OK;
   }
@@ -55,6 +58,7 @@ class GetOrCreateWorkerManagerRunnable final : public Runnable {
  private:
   nsCOMPtr<nsIEventTarget> mBackgroundEventTarget;
   RefPtr<SharedWorkerService> mService;
+  RefPtr<ThreadsafeContentParentHandle> mContentParentHandle;
   RefPtr<SharedWorkerParent> mActor;
   RemoteWorkerData mData;
   uint64_t mWindowID;
@@ -154,19 +158,23 @@ void SharedWorkerService::GetOrCreateWorkerManager(
     uint64_t aWindowID, const MessagePortIdentifier& aPortIdentifier) {
   AssertIsOnBackgroundThread();
 
+  RefPtr<ThreadsafeContentParentHandle> contentParentHandle =
+      BackgroundParent::GetContentParentHandle(aActor->Manager());
+
   // The real check happens on main-thread.
   RefPtr<GetOrCreateWorkerManagerRunnable> r =
-      new GetOrCreateWorkerManagerRunnable(this, aActor, aData, aWindowID,
-                                           aPortIdentifier);
+      new GetOrCreateWorkerManagerRunnable(this, contentParentHandle, aActor,
+                                           aData, aWindowID, aPortIdentifier);
 
   nsresult rv = SchedulerGroup::Dispatch(r.forget());
   (void)NS_WARN_IF(NS_FAILED(rv));
 }
 
 void SharedWorkerService::GetOrCreateWorkerManagerOnMainThread(
-    nsIEventTarget* aBackgroundEventTarget, SharedWorkerParent* aActor,
-    const RemoteWorkerData& aData, uint64_t aWindowID,
-    UniqueMessagePortId& aPortIdentifier) {
+    nsIEventTarget* aBackgroundEventTarget,
+    ThreadsafeContentParentHandle* aContentParentHandle,
+    SharedWorkerParent* aActor, const RemoteWorkerData& aData,
+    uint64_t aWindowID, UniqueMessagePortId& aPortIdentifier) {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aBackgroundEventTarget);
   MOZ_ASSERT(aActor);
@@ -180,17 +188,19 @@ void SharedWorkerService::GetOrCreateWorkerManagerOnMainThread(
   }
 
   nsCOMPtr<nsIPrincipal> principal = principalOrErr.unwrap();
+
+  nsCString currentRemoteType = aContentParentHandle
+                                    ? aContentParentHandle->GetRemoteType()
+                                    : NOT_REMOTE_TYPE;
   auto remoteType = RemoteWorkerManager::GetRemoteType(
-      principal, WorkerKind::WorkerKindShared);
+      principal, WorkerKind::WorkerKindShared, currentRemoteType);
   if (NS_WARN_IF(remoteType.isErr())) {
     ErrorPropagationOnMainThread(aBackgroundEventTarget, aActor,
                                  remoteType.unwrapErr());
     return;
   }
 
-  if (!remoteType.unwrap().Equals(copyData.remoteType())) {
-    copyData.remoteType() = remoteType.unwrap();
-  }
Loading diff…