Firefox Accepts a Service Worker Script Served as `application/json`
Categories
(Core :: DOM: Service Workers, defect)
Tracking
()
| 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:
- 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
-
The testcase serves a Service Worker script response with
Content-Type: application/json. -
The response body is valid JavaScript:
self.addEventListener('install', event => event.waitUntil(self.skipWaiting()));
self.addEventListener('activate', event => event.waitUntil(self.clients.claim()));
- As controls, run the same testcase with Firefox using
text/plain, and Chrome usingapplication/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/javascriptshould be acceptedapplication/jsonshould be rejectedtext/jsonshould be rejected- structured
+jsonMIME types should be rejected text/plainshould be rejected
Firefox should not register or activate a Service Worker from a response labeled as JSON.
Comment 1•4 months ago
|
||
In what scenario would this actually cause a security issue that materially harms users or website operators?
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.
Updated•4 months ago
|
Comment 3•4 months ago
|
||
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.
| Assignee | ||
Comment 4•4 months ago
|
||
| Assignee | ||
Updated•4 months ago
|
| Assignee | ||
Updated•3 months ago
|
Comment 6•3 months ago
|
||
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
| Assignee | ||
Updated•3 months ago
|
Comment 9•3 months ago
|
||
Comment 10•3 months ago
|
||
Please add a beta uplift request
Updated•3 months ago
|
| Assignee | ||
Comment 11•3 months ago
|
||
Original Revision: https://phabricator.services.mozilla.com/D308863
Updated•3 months ago
|
Comment 12•3 months ago
|
||
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
| Assignee | ||
Updated•3 months ago
|
Updated•3 months ago
|
Updated•3 months ago
|
Updated•3 months ago
|
Comment 13•3 months ago
|
||
| uplift | ||
Updated•3 months ago
|
Updated•3 months ago
|
Updated•1 month ago
|
Description
•