Medium firefox Cross Origin 🔧 Commit mapped

Overview

Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Impactmoderate
DescriptionSame-origin policy bypass in the Graphics: ImageLib component
ComponentNetworking
Bug ClassCross Origin
Tracker2061794
Fix commit3a34ba4f1072 (firefox) +4/-0
CISA KEVNot listed
CreditedThe Mozilla Fuzzing Team
Disclosed2026-08-18

Background

`InterceptedHttpChannel`
the HTTP channel used when a Service Worker intercepts a network request and synthesizes its own response.
`LoadTainting::Opaque`
the tainting state marking a cross-origin, no-CORS response whose body must stay hidden from the requesting origin.
`AllRedirectsSameOrigin` flag
a channel bit asserting that every hop of a load stayed same-origin, used downstream to decide whether a resource may be exposed cross-origin.
`StartSynthesizedResponse`
the InterceptedHttpChannel method that installs a Service-Worker-provided response and optionally follows synthetic redirects.

Root Cause Analysis

When a Service Worker synthesizes a response, InterceptedHttpChannel::StartSynthesizedResponse installs mSynthesizedResponseHead and proceeds without reconciling the channel’s AllRedirectsSameOrigin bookkeeping against the actual tainting of the synthesized load. The invariant that AllRedirectsSameOrigin must be false whenever the load is LoadTainting::Opaque (i.e., a cross-origin no-CORS result) was not enforced along the synthesized-response path, so an opaque cross-origin body could be presented as though all hops were same-origin. Downstream consumers that trust the AllRedirectsSameOrigin flag would then treat the tainted resource as safe to expose, defeating the same-origin policy.

The fix adds an explicit check: if mLoadInfo->GetTainting() == LoadTainting::Opaque, it calls StoreAllRedirectsSameOriginIgnoringInternal(false), forcing the flag to reflect the true cross-origin nature before ShouldRedirect() and later exposure decisions run. This restores the invariant precisely where the Service Worker’s opaque response entered the channel, closing the mismatch.

Key insight
The core mistake was failing to clear the AllRedirectsSameOrigin bit when a Service Worker synthesized an opaque, cross-origin response, letting tainted data inherit a same-origin trust label; the fix reasserts the invariant by forcing that flag to false for LoadTainting::Opaque loads.

Attack Path

  1. Register a malicious Service Worker An attacker controls a page whose Service Worker can intercept its subresource fetches.
  2. Fetch a cross-origin target The page requests a victim cross-origin resource in no-CORS mode, producing a LoadTainting::Opaque load.
  3. Synthesize an opaque response The Service Worker returns the opaque cross-origin response through StartSynthesizedResponse, where AllRedirectsSameOrigin is left incorrectly asserted.
  4. Consume as same-origin A downstream consumer that trusts AllRedirectsSameOrigin treats the tainted body as same-origin and permits reading it.
  5. Exfiltrate cross-origin data The attacker reads the otherwise-protected cross-origin content, achieving a same-origin policy bypass.

Impact Assessment

An attacker gains a same-origin policy bypass, reading cross-origin resource data that should remain opaque, within the content process driving a page that controls a Service Worker. The precondition is the ability to register a Service Worker on an attacker-controlled origin and route a no-CORS cross-origin fetch through it; the metadata rates the impact as moderate.

Files Changed

  • netwerk/protocol/http/InterceptedHttpChannel.cpp

Audit Directions

  • Tainting vs. same-origin flags
    Audit every path that sets or trusts AllRedirectsSameOrigin (or similar same-origin assertions) to confirm it is reconciled against LoadInfo::GetTainting() for opaque loads.
  • Service Worker synthesized responses
    Review other InterceptedHttpChannel and Fetch-interception entry points for security-relevant channel bits that are computed from network hops but bypassed when a response is synthesized.
  • Cross-origin exposure consumers
    Inspect callers that gate exposure or reads on same-origin flags to ensure they also honor tainting, so a single stale flag cannot unlock cross-origin data.
diff --git a/netwerk/protocol/http/InterceptedHttpChannel.cpp b/netwerk/protocol/http/InterceptedHttpChannel.cpp
index 7af3a4d44fc..f094d87b789 100644
--- a/netwerk/protocol/http/InterceptedHttpChannel.cpp
+++ b/netwerk/protocol/http/InterceptedHttpChannel.cpp
@@ -915,6 +915,10 @@ InterceptedHttpChannel::StartSynthesizedResponse(
 
   mResponseHead = std::move(mSynthesizedResponseHead);
 
+  if (mLoadInfo->GetTainting() == LoadTainting::Opaque) {
+    StoreAllRedirectsSameOriginIgnoringInternal(false);
+  }
+
   if (ShouldRedirect()) {
     rv = FollowSyntheticRedirect();
     NS_ENSURE_SUCCESS(rv, rv);
Loading diff…