Open
Bug 1467998
Opened 6 years ago
Updated 6 months ago
<script> element without "cross-origin" attribute treats service worker synthesized CORS response as opaque
Categories
(Core :: DOM: Service Workers, defect, P3)
Tracking
()
REOPENED
People
(Reporter: prakashsharma97, Unassigned)
References
(Blocks 1 open bug)
Details
(Whiteboard: dom-lws-bugdash-triage)
User Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36
Steps to reproduce:
Visit https://raw.cm2.pw/Firefox/
Actual results:
The script error, "ReferenceError: foo is not defined", is written in <textarea>. Though the `script` src is is of same-origin, the request is intercepted and changed by Service Worker which first fetches the content from https://api.ipify.org/?callback=foo&format=jsonp and appends `/* ALTERED */`.
The content, however, is made readable with CORS policy. If the content is not readable or requested with 'no-cors', a generic "script error" is thrown. Thus, the behavior cannot be considered a security/privacy issue.
Expected results:
Errors should only be available to same-origin requests.
Comment 1•6 years ago
|
||
I managed to reproduce the issue on Firefox 60.0.2, Firefox 61.0b7, and Nightly 62.0a1 (2018-06-12), on Windows 10, Ubuntu 16.04 and Mac OS.
Marking it as new on DOM:Service Workers component.
Status: UNCONFIRMED → NEW
status-firefox60:
--- → affected
status-firefox61:
--- → affected
status-firefox62:
--- → affected
Component: Untriaged → DOM: Service Workers
Ever confirmed: true
OS: Unspecified → All
Product: Firefox → Core
Version: 60 Branch → Trunk
Reporter | ||
Comment 2•6 years ago
|
||
FYI, it works in all modern browsers (Safari, not testd). I'm not sure if it's intentional or if I should report it to all vendors.
Comment 3•6 years ago
|
||
The service worker script is not actually passing a cors response to respondWith(). Its doing this:
self.addEventListener('fetch', event => {
let [,url] = event.request.url.match(/fake\.php\?url=(.+)/) || [];
if(url){
console.info('Bypassing SOP for: ' + url);
event.respondWith(modify(unescape(url)));
}
});
const modify = url => {
return fetch(url, {mode: 'cors', redirect: 'follow'}).then(response=>response.text()).then(text=>{
if(text) console.log(text);
return new Response(text + '/* ALTERED */');
});
}
In particular note that its doing:
return new Response(text + '/* ALTERED */');
This is synthesizing a new Response without any associated URL. The browser has no practical way to tell if the body that was based to such a Response constructor originated from a CORS cross-origin source.
So this behavior is expected and by design. An origin is allowed to lie to itself via its own same-origin service worker. And we allow the service worker to read cross-origin CORS-protected data.
One question, though, if you change your test to return the CORS response from the fetch() directly without altering it, what happens? I expect you should get muted script errors in firefox in that case.
Comment 4•6 years ago
|
||
The whole idea behind <script crossorigin> is that you get non-muted errors for cross-origin scripts. This is all by design.
Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → INVALID
Comment 5•6 years ago
|
||
Well, the <script> element in this case does not have the cross-origin attribute.
Comment 6•6 years ago
|
||
Ah right, in that case per the standard it should not be muted. If we do, we might want to fix that. I'll reopen.
Status: RESOLVED → REOPENED
Resolution: INVALID → ---
Updated•6 years ago
|
Priority: -- → P2
Reporter | ||
Comment 7•6 years ago
|
||
(In reply to Ben Kelly [:bkelly] from comment #3)
> One question, though, if you change your test to return the CORS response
> from the fetch() directly without altering it, what happens? I expect you
> should get muted script errors in firefox in that case.
Yeah, if I return cors response from fetch() directly, I get generic "script errors" message.
Comment 8•6 years ago
|
||
Ok. Anne, do you think that is a bug then? I guess the error muting CORs type check should use the actual response type?
Flags: needinfo?(annevk)
Comment 9•6 years ago
|
||
Yeah, at least as far as I can remember we didn't change the standard on the response being authoritative (even though most implementations work differently for the moment). (We did add a restriction that a "same-origin" fetch cannot take a "cors" response as that would result in rather tricky downstream scenarios.)
Flags: needinfo?(annevk)
Comment 10•6 years ago
|
||
Ok, then this is very similar to bug 1467454. I'll morph this bug into a similar issue for script muting.
The fix should be to adjust this code:
https://searchfox.org/mozilla-central/rev/d544b118e26422877108c42723b26e9bb4539721/dom/script/ScriptLoader.cpp#2101
To look at the LoadInfo tainting value instead of doing a cross-origin principal subsumes check. Or maybe it could do both if we want a system principal to still be able to get full script errors even for an opaque tainted result.
Blocks: ServiceWorkers-compat
Summary: Service Worker - Script error leakage if CORS enabled → <script> element without "cross-origin" attribute treats service worker synthesized CORS response as opaque
Updated•2 years ago
|
Severity: normal → S3
Updated•6 months ago
|
Priority: P2 → P3
Whiteboard: dom-lws-bugdash-triage
You need to log in
before you can comment on or make changes to this bug.
Description
•