Closed Bug 2044063 (CVE-2026-16407) Opened 4 months ago Closed 3 months ago

Firefox Accepts a Service Worker Script Served as `application/json`

Categories

(Core :: DOM: Service Workers, defect)

Firefox 151
defect

Tracking

()

RESOLVED FIXED
154 Branch
Tracking Status
firefox-esr115 --- unaffected
firefox-esr140 --- unaffected
firefox152 --- wontfix
firefox153 + fixed
firefox154 + fixed

People

(Reporter: 1705004398, Assigned: hsingh)

Details

(Keywords: csectype-mitigation-bypass, reporter-external, sec-low, Whiteboard: [adv-main153+])

Attachments

(1 file, 2 external files)

11.16 KB, application/x-zip-compressed
Details

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:151.0) Gecko/20100101 Firefox/151.0

Steps to reproduce:

I tested whether Firefox accepts a Service Worker script response served with Content-Type: application/json when the response body is valid JavaScript.

Steps:

  1. From the report directory, run the Firefox testcase in JSON mode:
python3 attachments/repro.py \
  --browser firefox \
  --browser-binary /path/to/firefox \
  --driver-binary /path/to/geckodriver \
  --mode json
  1. The testcase serves a Service Worker script response with Content-Type: application/json.

  2. The response body is valid JavaScript:

self.addEventListener('install', event => event.waitUntil(self.skipWaiting()));
self.addEventListener('activate', event => event.waitUntil(self.clients.claim()));
  1. As controls, run the same testcase with Firefox using text/plain, and Chrome using application/json:
python3 attachments/repro.py \
  --browser firefox \
  --browser-binary /path/to/firefox \
  --driver-binary /path/to/geckodriver \
  --mode text

python3 attachments/repro.py \
  --browser chrome \
  --browser-binary /path/to/chrome \
  --driver-binary /path/to/chromedriver \
  --mode json

Actual results:

Firefox accepts, registers, and activates the Service Worker script even though the script response is served as Content-Type: application/json.

The affected Firefox output includes:

"report": {
  "kind": "sw-json-mime",
  "mode": "json",
  "accepted": "true"
}

The same JavaScript body served as text/plain is rejected by Firefox.

Chrome also rejects the application/json Service Worker script response with an unsupported MIME type error.

This means Firefox's Service Worker script MIME check appears to allow JSON MIME types, then parses the response body as a Service Worker script.

Expected results:

Firefox should reject Service Worker script responses served with JSON MIME types such as application/json.

A Service Worker script should require a JavaScript MIME type. JSON MIME types should not be accepted as Service Worker scripts, even if the response body is syntactically valid JavaScript.

Expected behavior:

  • application/javascript should be accepted
  • application/json should be rejected
  • text/json should be rejected
  • structured +json MIME types should be rejected
  • text/plain should be rejected

Firefox should not register or activate a Service Worker from a response labeled as JSON.

In what scenario would this actually cause a security issue that materially harms users or website operators?

Group: firefox-core-security → dom-core-security
Component: Untriaged → DOM: Service Workers
Flags: needinfo?(1705004398)
Product: Firefox → Core

Thanks for taking a look.

A realistic scenario would be a site with a same-origin JSON/upload/export endpoint where an attacker can influence the response bytes, plus some way to trigger registration to that URL. In browsers that enforce the MIME check, this should fail because the response is JSON. In affected Firefox, it gets registered and activated as a Service Worker.

That can turn control over a same-origin JSON-labeled resource into persistent Service Worker control, allowing interception of future same-origin navigations/fetches within the scope.

So the issue is specifically the Service Worker script MIME gate, not cross-origin registration.

Flags: needinfo?(1705004398)

I wonder if this regressed from bug 1990925? That tried to allow JSON modules to be loaded by workers, but the worker itself needed to have a JavaScript MIME type still. But maybe loadContext->IsTopLevel() doesn't work in a ServiceWorker context? I'd be quite surprised if there weren't WPT for this, but if there were why didn't the test failure trigger a bug on it already? Maybe I just missed it.

It's hard to imagine a scenario where this would be plausibly useful as a vulnerability, unless the site is already full of security holes. Would a site actually allow the upload of JSON files that are not valid JSON but actually syntactically valid scripts? I can certainly imagine insecure sites that allow uploads with few restrictions, but in that case upload an HTML or SVG file as your attack. And then somehow you have to get the site to load a serviceworker given that URL. A site is not normally going to try to load a JSON file as a service worker so that would seem to require an XSS on the site to start with.

It's definitely a spec violation and bug, and maybe it could have been a small part in an exploit chain with some other more serious bugs (probably in the web app, not the browser), but that's pretty speculative.

Status: UNCONFIRMED → NEW
Ever confirmed: true
Flags: needinfo?(hsingh)
Keywords: sec-low
Attached file (secure) —
Assignee: nobody → hsingh
Flags: needinfo?(hsingh)
Severity: -- → S3
Pushed by hsingh@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/4f7060aa7884 https://hg.mozilla.org/integration/autoland/rev/403089095d24 Fixing a service worker issue where a json mime type can be registered as a valid sw script.r=dom-worker-reviewers,edenchuang

TEST-UNEXPECTED-PASS | /html/semantics/scripting-1/the-script-element/json-module/json-module-service-worker-test.https.html | Trying to register a service worker with a top-level JSON Module should fail - expected FAIL

Flags: needinfo?(hsingh)
Pushed by ctuns@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/26b5f0619789 https://hg.mozilla.org/integration/autoland/rev/1d3a40fd78bf Revert "Bug 2044063: Fixing a service worker issue where a json mime type can be registered as a valid sw script.r=dom-worker-reviewers,edenchuang" for causing wpt failures in /json-module-service-worker-test.https.html
Status: NEW → ASSIGNED
Flags: needinfo?(hsingh)
Pushed by hsingh@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/e4280fe04522 https://hg.mozilla.org/integration/autoland/rev/f88470063676 Fixing a service worker issue where a json mime type can be registered as a valid sw script.r=dom-worker-reviewers,edenchuang
Group: dom-core-security → core-security-release
Status: ASSIGNED → RESOLVED
Closed: 3 months ago
Resolution: --- → FIXED
Target Milestone: --- → 154 Branch

Please add a beta uplift request

Attached file (secure) —
Attachment #9607199 - Flags: approval-mozilla-beta?

firefox-beta Uplift Approval Request

  • User impact if declined/Reason for urgency: A valid service worker can be served as application/json mime type. This should have been stopped as a top-level script could be disguised as a JSON.
  • Code covered by automated testing?: yes
  • Fix verified in Nightly?: yes
  • Needs manual QE testing?: no
  • Steps to reproduce for manual QE testing:
  • Risk associated with taking this patch: low
  • Explanation of risk level: Low risk.
  • String changes made/needed?: NA
  • Is Android affected?: yes
Flags: needinfo?(hsingh)
Flags: in-testsuite+
Attachment #9607199 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
Whiteboard: [adv-main153+]
Alias: CVE-2026-16407
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: