Low firefox Logic Error 🔧 Commit mapped

Overview

Low
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impactlow
DescriptionMitigation bypass in the DOM: Security component
ComponentDOM
Bug ClassLogic Error
Tracker2016915
Fix commitfa33a51e85e6 (firefox) +248/-169
CISA KEVNot listed
Creditedlebr0nli
Disclosed2026-04-21

Changed Functions

FunctionChangeNotes
CreateFromCSP
dom/security/OffThreadCSPContext.cpp
modified
WorkerCSPContext
dom/security/OffThreadCSPContext.h
modified
OffThreadCSPContext
dom/security/OffThreadCSPContext.h
modified
if
dom/workers/WorkerLoadInfo.cpp
modified

Files Changed

  • dom/security/OffThreadCSPContext.cpp
  • dom/security/OffThreadCSPContext.h
  • dom/security/moz.build
  • dom/security/trusted-types/TrustedTypePolicyFactory.cpp
  • dom/workers/RuntimeService.cpp
  • dom/workers/WorkerCSPContext.cpp
  • dom/workers/WorkerCSPContext.h
  • dom/workers/WorkerLoadInfo.cpp
  • dom/workers/WorkerLoadInfo.h
  • dom/workers/WorkerPrivate.cpp
  • dom/workers/WorkerPrivate.h
  • dom/workers/moz.build
  • dom/workers/remoteworkers/RemoteWorkerChild.cpp
  • dom/worklet/WorkletImpl.cpp
  • dom/worklet/WorkletImpl.h
  • dom/worklet/WorkletThread.cpp
diff --git a/dom/workers/WorkerCSPContext.cpp b/dom/security/OffThreadCSPContext.cpp
similarity index 79%
rename from dom/workers/WorkerCSPContext.cpp
rename to dom/security/OffThreadCSPContext.cpp
index cefbac2c1bc..a06a1a86e73 100644
--- a/dom/workers/WorkerCSPContext.cpp
+++ b/dom/security/OffThreadCSPContext.cpp
@@ -2,11 +2,10 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "WorkerCSPContext.h"
+#include "OffThreadCSPContext.h"
 
+#include "MainThreadUtils.h"
 #include "mozilla/StaticPrefs_dom.h"
-#include "mozilla/dom/WorkerCommon.h"
-#include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/nsCSPParser.h"
 #include "mozilla/dom/nsCSPUtils.h"
 #include "mozilla/ipc/BackgroundUtils.h"
@@ -15,24 +14,24 @@
 namespace mozilla::dom {
 
 /* static */
-Result<UniquePtr<WorkerCSPContext>, nsresult> WorkerCSPContext::CreateFromCSP(
-    nsIContentSecurityPolicy* aCSP) {
-  AssertIsOnMainThread();
+Result<UniquePtr<OffThreadCSPContext>, nsresult>
+OffThreadCSPContext::CreateFromCSP(nsIContentSecurityPolicy* aCSP) {
+  MOZ_ASSERT(NS_IsMainThread());
 
   mozilla::ipc::CSPInfo cspInfo;
   nsresult rv = CSPToCSPInfo(aCSP, &cspInfo);
   if (NS_FAILED(rv)) {
     return Err(rv);
   }
-  return MakeUnique<WorkerCSPContext>(std::move(cspInfo));
+  return MakeUnique<OffThreadCSPContext>(std::move(cspInfo));
 }
 
-const nsTArray<UniquePtr<const nsCSPPolicy>>& WorkerCSPContext::Policies() {
+const nsTArray<UniquePtr<const nsCSPPolicy>>& OffThreadCSPContext::Policies() {
   EnsureIPCPoliciesRead();
   return mPolicies;
 }
 
-bool WorkerCSPContext::IsEvalAllowed(bool& aReportViolation) {
+bool OffThreadCSPContext::IsEvalAllowed(bool& aReportViolation) {
   MOZ_ASSERT(!aReportViolation);
 
   bool trustedTypesRequired =
@@ -54,7 +53,7 @@ bool WorkerCSPContext::IsEvalAllowed(bool& aReportViolation) {
   return true;
 }
 
-bool WorkerCSPContext::IsWasmEvalAllowed(bool& aReportViolation) {
+bool OffThreadCSPContext::IsWasmEvalAllowed(bool& aReportViolation) {
   MOZ_ASSERT(!aReportViolation);
   for (const UniquePtr<const nsCSPPolicy>& policy : Policies()) {
     // Either 'unsafe-eval' or 'wasm-unsafe-eval' can allow this
@@ -71,8 +70,8 @@ bool WorkerCSPContext::IsWasmEvalAllowed(bool& aReportViolation) {
   return true;
 }
 
-void WorkerCSPContext::EnsureIPCPoliciesRead() {
-  MOZ_DIAGNOSTIC_ASSERT(!!GetCurrentThreadWorkerPrivate());
+void OffThreadCSPContext::EnsureIPCPoliciesRead() {
+  MOZ_ASSERT(!NS_IsMainThread());
 
   if (!mPolicies.IsEmpty() || mCSPInfo.policyInfos().IsEmpty()) {
     return;
diff --git a/dom/workers/WorkerCSPContext.h b/dom/security/OffThreadCSPContext.h
similarity index 68%
rename from dom/workers/WorkerCSPContext.h
rename to dom/security/OffThreadCSPContext.h
index f33d497feee..5f73b14b23e 100644
--- a/dom/workers/WorkerCSPContext.h
+++ b/dom/security/OffThreadCSPContext.h
@@ -2,8 +2,8 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef mozilla_dom_workers_WorkerCSPContext_h_
-#define mozilla_dom_workers_WorkerCSPContext_h_
+#ifndef mozilla_dom_OffThreadCSPContext_h_
+#define mozilla_dom_OffThreadCSPContext_h_
 
 #include "mozilla/Result.h"
 #include "mozilla/UniquePtr.h"
@@ -15,12 +15,13 @@ class nsIContentSecurityPolicy;
 
 namespace mozilla::dom {
 
-// A minimal version of nsCSPContext that can run on Worker threads.
-class WorkerCSPContext final {
+// A minimal version of nsCSPContext that can run on worker and worklet threads.
+class OffThreadCSPContext final {
  public:
-  explicit WorkerCSPContext(mozilla::ipc::CSPInfo&& aInfo) : mCSPInfo(aInfo) {}
+  explicit OffThreadCSPContext(mozilla::ipc::CSPInfo&& aInfo)
+      : mCSPInfo(aInfo) {}
 
-  static Result<UniquePtr<WorkerCSPContext>, nsresult> CreateFromCSP(
+  static Result<UniquePtr<OffThreadCSPContext>, nsresult> CreateFromCSP(
       nsIContentSecurityPolicy* aCSP);
 
   const mozilla::ipc::CSPInfo& CSPInfo() const { return mCSPInfo; }
@@ -35,15 +36,14 @@ class WorkerCSPContext final {
   // Thread boundaries require us to not only store a CSP object, but also a
   // serialized version of the CSP. Reason being: Serializing a CSP to a CSPInfo
   // needs to happen on the main thread, but storing the CSPInfo needs to happen
-  // on the worker thread. We move the CSPInfo into the Client within
-  // ScriptExecutorRunnable::PreRun().
+  // on the worker/worklet thread.
   mozilla::ipc::CSPInfo mCSPInfo;
 
-  // This is created lazily by parsing the policies in CSPInfo on the worker
-  // thread.
+  // This is created lazily by parsing the policies in CSPInfo on the
+  // worker/worklet thread.
   nsTArray<UniquePtr<const nsCSPPolicy>> mPolicies;
 };
 
 }  // namespace mozilla::dom
 
-#endif  // mozilla_dom_workers_WorkerCSPContext_h_
+#endif  // mozilla_dom_OffThreadCSPContext_h_
diff --git a/dom/security/moz.build b/dom/security/moz.build
index 147a4dacf3e..f865c75a2a9 100644
--- a/dom/security/moz.build
+++ b/dom/security/moz.build
@@ -29,6 +29,7 @@ EXPORTS.mozilla.dom += [
     "nsHTTPSOnlyStreamListener.h",
     "nsHTTPSOnlyUtils.h",
     "nsMixedContentBlocker.h",
+    "OffThreadCSPContext.h",
     "PolicyContainer.h",
     "PolicyTokenizer.h",
     "ReferrerInfo.h",
@@ -64,6 +65,7 @@ UNIFIED_SOURCES += [
     "nsHTTPSOnlyStreamListener.cpp",
     "nsHTTPSOnlyUtils.cpp",
     "nsMixedContentBlocker.cpp",
+    "OffThreadCSPContext.cpp",
     "PolicyContainer.cpp",
     "PolicyTokenizer.cpp",
     "ReferrerInfo.cpp",
diff --git a/dom/security/trusted-types/TrustedTypePolicyFactory.cpp b/dom/security/trusted-types/TrustedTypePolicyFactory.cpp
index 656a56126f2..ab5ed351972 100644
--- a/dom/security/trusted-types/TrustedTypePolicyFactory.cpp
+++ b/dom/security/trusted-types/TrustedTypePolicyFactory.cpp
@@ -157,7 +157,7 @@ auto TrustedTypePolicyFactory::ShouldTrustedTypePolicyCreationBeBlockedByCSP(
     if (NS_WARN_IF(rv.Failed())) {
       rv.SuppressException();
     }
-    if (WorkerCSPContext* ctx = workerPrivate->GetCSPContext()) {
+    if (OffThreadCSPContext* ctx = workerPrivate->GetCSPContext()) {
       for (const UniquePtr<const nsCSPPolicy>& policy : ctx->Policies()) {
         if (shouldBlock(policy.get())) {
           result = PolicyCreation::Blocked;
diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp
index 477490a0849..2d7ef850680 100644
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -555,12 +555,12 @@ MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION bool ContentSecurityPolicyAllows(
       return true;
     }
 
-    if (WorkerCSPContext* ctx = worker->GetCSPContext()) {
+    if (OffThreadCSPContext* ctx = worker->GetCSPContext()) {
       evalOK = ctx->IsEvalAllowed(reportViolation);
     }
     violationType = nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL;
   } else {
-    if (WorkerCSPContext* ctx = worker->GetCSPContext()) {
+    if (OffThreadCSPContext* ctx = worker->GetCSPContext()) {
       evalOK = ctx->IsWasmEvalAllowed(reportViolation);
     }
 
diff --git a/dom/workers/WorkerLoadInfo.cpp b/dom/workers/WorkerLoadInfo.cpp
index 9a10f3654e5..5d2542e984e 100644
--- a/dom/workers/WorkerLoadInfo.cpp
+++ b/dom/workers/WorkerLoadInfo.cpp
@@ -113,8 +113,8 @@ nsresult WorkerLoadInfo::SetPrincipalsAndCSPOnMainThread(
   mCSP = aCsp;
 
   if (mCSP) {
-    Result<UniquePtr<WorkerCSPContext>, nsresult> ctx =
-        WorkerCSPContext::CreateFromCSP(aCsp);
+    Result<UniquePtr<OffThreadCSPContext>, nsresult> ctx =
+        OffThreadCSPContext::CreateFromCSP(aCsp);
     if (NS_WARN_IF(ctx.isErr())) {
       return ctx.unwrapErr();
     }
diff --git a/dom/workers/WorkerLoadInfo.h b/dom/workers/WorkerLoadInfo.h
index a52a8cb1663..63b0645991d 100644
--- a/dom/workers/WorkerLoadInfo.h
+++ b/dom/workers/WorkerLoadInfo.h
@@ -12,8 +12,8 @@
Loading diff…