High CVSS 7.5 firefox Cross Origin 🔧 Commit mapped

Overview

High
Severity
7.5
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionAn attacker could, via a specially crafted multipart response, execute arbitrary JavaScript under the `resource://devtools` origin. This could allow them to access cross-origin JSON content. This access is limited to "same site" documents by the Site Isolation feature on desktop clients, but full cross-origin access is possible on Android versions.
ComponentCore
Bug ClassCross Origin
Tracker1918874
Fix commite5a95be806bd (firefox) +7/-1
CWECWE-79 (Cross-site scripting)
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
CISA KEVNot listed
CreditedMasato Kinugawa
Disclosed2024-10-01

Background

JSON Viewer
a DevTools feature implemented in converter-child.js that intercepts application/json responses and renders them as an interactive HTML page served from the privileged resource://devtools origin.
Stream converter
an nsIStreamConverter implementation (here Converter) that Firefox invokes to transform a channel’s response body from one MIME type to another, deciding the output type via getConvertedType.
`nsIMultiPartChannel`
an interface implemented by channels carrying a multipart/x-mixed-replace response, where a single request yields multiple sequential document parts.
Site Isolation
a desktop-only architecture that separates web content into per-site processes, limiting the reach of a compromised origin to same-site documents.

Root Cause Analysis

The vulnerable path is Converter.prototype.getConvertedType, which unconditionally returned "text/html" for any JSON response, causing the JSON Viewer to load privileged resource://devtools markup to display the data. The implicit invariant was that a single JSON response maps to a single JSON Viewer document, but a multipart/x-mixed-replace response delivered through an nsIMultiPartChannel violated this by supplying attacker-controlled subsequent parts within the same privileged origin, letting crafted content run as JavaScript under resource://devtools. Because that origin can issue cross-origin fetches for JSON, the injected script could exfiltrate cross-origin JSON content.

The fix makes getConvertedType accept the originating channel, detect when it instanceof Ci.nsIMultiPartChannel, and throw an NS_ERROR_FAILURE exception instead of converting, so multipart responses never reach the privileged renderer.

Key insight
The core mistake was treating every JSON channel as safe to render in the privileged JSON Viewer without distinguishing single-part from multipart responses; the fix closes this by rejecting nsIMultiPartChannel channels in getConvertedType before any conversion to "text/html" occurs.

Attack Path

  1. Serve a multipart JSON response The attacker configures a server to return a multipart/x-mixed-replace response with a JSON content type, delivered to Firefox over an nsIMultiPartChannel.
  2. Trigger the JSON Viewer Firefox routes the JSON MIME type to the Converter stream converter, whose getConvertedType returns "text/html" and loads the JSON Viewer under resource://devtools.
  3. Inject a hostile part A later part of the multipart stream carries crafted content that executes as JavaScript within the privileged resource://devtools origin rather than as inert displayed data.
  4. Read cross-origin JSON The injected script uses the privileged origin’s fetch capability to retrieve JSON from other origins and exfiltrate it.

Impact Assessment

An attacker gains arbitrary JavaScript execution in the privileged resource://devtools origin within the content/DevTools context, enabling theft of cross-origin JSON data. On desktop this is constrained to same-site documents by Site Isolation, but on Android full cross-origin access is possible. The only precondition is that the victim navigates to or fetches an attacker-controlled multipart JSON response.

Changed Functions

FunctionChangeNotes
asyncConvertData
devtools/client/jsonview/converter-child.js
modified
getConvertedType
devtools/client/jsonview/converter-child.js
modified
if
devtools/client/jsonview/converter-child.js
modified

Files Changed

  • devtools/client/jsonview/converter-child.js

Audit Directions

  • Privileged-origin renderers
    Review other nsIStreamConverter and content-type handlers that load UI into resource:// or chrome:// origins to ensure they reject or sanitize multipart and streaming channels.
  • Channel-type assumptions
    Look for code that inspects only a response’s MIME type while ignoring the concrete channel interface (such as nsIMultiPartChannel), since a single logical response may deliver multiple attacker-controlled parts.
  • Cross-origin fetch from privileged contexts
    Audit features running under privileged origins that can perform cross-origin requests, verifying that untrusted document content can never be injected into that origin.
diff --git a/devtools/client/jsonview/converter-child.js b/devtools/client/jsonview/converter-child.js
index e249de01802..3c8c9fcc5dc 100644
--- a/devtools/client/jsonview/converter-child.js
+++ b/devtools/client/jsonview/converter-child.js
@@ -72,7 +72,13 @@ Converter.prototype = {
   asyncConvertData(fromType, toType, listener) {
     this.listener = listener;
   },
-  getConvertedType() {
+  getConvertedType(_fromType, channel) {
+    if (channel instanceof Ci.nsIMultiPartChannel) {
+      throw new Components.Exception(
+        "JSONViewer doesn't support multipart responses.",
+        Cr.NS_ERROR_FAILURE
+      );
+    }
     return "text/html";
   },
 
Loading diff…