Low firefox Logic Error 🔧 Commit mapped

Overview

Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Impactlow
DescriptionSite isolation issue in the CSS Parsing and Computation component
ComponentDOM
Bug ClassLogic Error
Tracker2060048
Fix commit4b53c716cbe5 (firefox) +17/-0
CISA KEVNot listed
Credited5up3rh3i
Disclosed2026-08-18

Background

`GetSubresourceCacheValidationInfo`
nsContentUtils helper that decides whether a fetched subresource may be reused from a shared cache or must be revalidated per document.
`Vary` header
an HTTP response header naming the request headers that a response’s content depends on, signaling that different header values yield different bodies.
`mMustRevalidate`
a flag in the validation-info struct that, when set, forces the subresource to be re-fetched/re-validated rather than served from a cross-document cache.
Subresource cache
Firefox’s per-process in-memory cache that lets multiple documents reuse an already-parsed resource (e.g. a CSS stylesheet) to save work.

Root Cause Analysis

The vulnerable path was nsContentUtils::GetSubresourceCacheValidationInfo, which computed cacheability for a subresource fetched over HTTP without inspecting the response’s Vary header. The invariant being violated is that a cached response may only be shared across documents when its body does not depend on request-specific, context-sensitive inputs such as the request’s cookies. Because Vary: Cookie (or the catch-all Vary: *) was ignored, a response whose content legitimately varies per user/session could be stored once and then served to a different document that carried different cookies, defeating the site-isolation/caching boundary.

The fix reads the vary response header and, when it is not already forced to revalidate, tokenizes the comma-separated list and sets info.mMustRevalidate = true if any token is * or (case-insensitively) cookie. This ensures cookie-dependent (or wildcard-varying) responses are revalidated instead of blindly reused, restoring the requirement that shared cache entries be context-independent.

Key insight
The single mistake was treating a subresource as freely cacheable across documents while ignoring the Vary header that declares the response depends on request-specific data like cookies. The fix closes this by forcing revalidation whenever Vary contains cookie or the * wildcard.

Attack Path

  1. Serve a cookie-varying resource An attacker (or a shared-hosting scenario) serves a subresource, e.g. a stylesheet, with Vary: Cookie so its body legitimately differs per session.
  2. Prime the cache One document fetches the resource, and the response is stored in the shared subresource cache without any must-revalidate flag.
  3. Reuse across context A second document with different cookies requests the same URL and is served the stale, previously-cached body instead of a fresh, cookie-appropriate response.
  4. Observe the mismatch The consuming document sees content computed from another context’s cookies, leaking state across the isolation boundary the Vary header was meant to enforce.

Impact Assessment

An attacker gains a cross-document/cross-context information-disclosure or state-confusion primitive within the content process, where a cookie- or wildcard-varying subresource can be served from cache to a document that should have received a different response. Preconditions are that the target resource is delivered over HTTP with Vary: Cookie or Vary: * and is fetched by more than one document sharing the cache. Rated low severity and low impact, consistent with a logic/site-isolation flaw rather than memory corruption.

Changed Functions

FunctionChangeNotes
if
dom/base/nsContentUtils.cpp
modified

Files Changed

  • dom/base/nsContentUtils.cpp

Audit Directions

  • Cache-key completeness
    Review other cross-document or shared caches to confirm they honor Vary (especially Cookie and *) before reusing a response, since a missing Vary check silently breaks context isolation.
  • Header tokenization
    Audit uses of nsCCharSeparatedTokenizer on HTTP header values for correct trimming and case-insensitive matching so tokens like cookie are not missed due to whitespace or casing.
  • Revalidation defaults
    Check subresource-loading paths that default to cacheable-without-revalidation and ensure each accounts for authorization- or session-sensitive response variance before treating an entry as safely shareable.
diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp
index 6814ff6c951..2cd762c75b0 100644
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -13577,6 +13577,23 @@ nsContentUtils::GetSubresourceCacheValidationInfo(nsIRequest* aRequest,
     if (!info.mMustRevalidate) {
       (void)httpChannel->IsNoCacheResponse(&info.mMustRevalidate);
     }
+
+    if (!info.mMustRevalidate) {
+      nsAutoCString vary;
+      (void)httpChannel->GetResponseHeader("vary"_ns, vary);
+      info.mMustRevalidate = [&] {
+        for (const nsACString& token :
+             nsCCharSeparatedTokenizer(vary, ',').ToRange()) {
+          if (token.EqualsLiteral("*")) {
+            return true;
+          }
+          if (token.EqualsIgnoreCase("cookie")) {
+            return true;
+          }
+        }
+        return false;
+      }();
+    }
   }
 
   // data: URIs are safe to cache across documents under any circumstance, so we
Loading diff…