-
Notifications
You must be signed in to change notification settings - Fork 312
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Receivers of ranged responses must ensure all ranges come from the same underlying resource #703
Comments
Sure. Does this work? |
Hmm, synthetic 206/304 should probably be a network error for APIs other than |
Also, that doesn't work as the |
It is leaked, at least in Chrome. |
Test this: Here it's just demonstrating truncation as the 3 bytes it replaces are the same (Ogg), but you can construct a more complicated service worker that mixes and matches. |
One thing that might be interesting is that some media fomats might have
trailing checksums or something like that, which we could use to read data
crossorigin byte by byte (by making 256 requests per byte - where each
payload is only valid for a checksum with the last byte being what we
check).
This might be easier on compression formats too (we just define a byte
sequence to be a sequence in a Huffman table, maybe).
|
That is only true if there are no implementation bugs at play here, right? But either way I guess range requests deserve more inspection. |
When the file size is big, audio/video element will send multiple requests.
I don't understand what "network layer" means in this situation. |
@horo-t no, it should be handled by the SW. What is unclear to me is what layer should be responsible for setting the range headers?
That determines how observable they are (most headers such as Separately we need to decide what happens with synthetic 206 responses. @mayhemer you probably want to review this thread. |
/cc @mnot |
@annevk I think the audio/video element (or other consumer) will be generating the Range headers in this situation. There's another use case where they're generated in cache/network, but that's when the HTTP cache has a partial response already there and it wants to "fill it in." When that happens, it really is opaque to SW and the API, because the response is a 200 (unless the API asked for a partial response to begin with, see above). I think this needs to be updated with the outcome of discussion at TPAC... |
Chrome has changed this since the bug was filed. @horo-t can correct me if I'm wrong, but my understanding is now we disallow mixing ranged responses from different origins. Furthermore, this change didn't have much to do with service worker, except that we are sure to use the response URL, not the original request URL in case the SW did respondWith(fetch(some-other-origin)). Also, we don't allow mixing of responses between network and SW-generated via new Response(). See https://code.google.com/p/chromium/issues/detail?id=505829 |
We disallow mixing ranged responses from different origins. See https://code.google.com/p/chromium/issues/detail?id=532569 We have layout test for this. |
F2F:
|
F2F: Need to do research around this
|
They seems to allow. Saw this many times our CDN, it returns 200 for ranged requests and browsers work fine. |
I wrote a gecko bug to block cache.put() of 206 responses: https://bugzilla.mozilla.org/show_bug.cgi?id=1264181 It seems we still need research to determine other aspects of this? |
200 is absolutely allowed as a response to a ranged request; servers aren't required to support them. http://httpwg.org/specs/rfc7233.html#introduction
|
Glad to know, but...
I wish this were true, but it doesn't seem like Chrome is currently doing this with Audio element. I've documented this, and would appreciate confirmation as to whether: 1. my bad, 2. Chrome's bad, 3. SW's bad |
I need to do more research on this. The spec says it's ok, so it seems like Chrome is bad. But if all browsers behave like Chrome, we should probably update the fetch spec to recognise this, then make the cache API generate ranges responses where it's safe to. |
@code-tree Do you have a sample site demonstrating the problem? I'd like to test in FF. Thanks. |
Yes, I created one today. I've also included a workaround based on a link @jakearchibald sent, and made it a bit more robust. I was hoping if I removed the 'Accept-Ranges' header from responses, then Chrome would stop requesting for ranges, but it didn't work. Only workaround seems to be to satisfy Chrome, and give it its ranged content. |
Thanks! Firefox seems to work with both cases on that site even with seeking the audio. On my mobile, though, so not sure if it's trying to use range requests or not. |
I also just realised it is working in Chrome mobile as well for me. The issue is quite hard to reproduce actually. I'm definitely reproducing it on desktop Chrome, and also know that it occurs on mobile too, in an app I'm not able to publish yet. Chrome dev tools (connected to mobile Chrome) actually shows a request for range 0-1 for both audio players, then when I click play it doesn't show any more requests (but does get the rest of the audio), making me wonder if there is also |
Update: Just realised I was using Chrome 50 for mobile testing, and it does not work (as evident when offline). Chrome pre-52 apparently uses Android's media stack (rather than own) and In any case, example with no range support does not work on any mobile Chrome version. Example with range support does not work for Chrome mobile < 52, but does work 52+. See also chrome bug 575357 and an upcoming Google post. And this quote from 7 Aug 2014 explains it... :/
|
Pre F2F notes: I don't think there's anything to discuss here |
Nothing to discuss because Chrome on Android now uses the Chrome media stack? Or for some other reason? |
This ticket was already decided, and there's no objection to the decision. Just need to submit PRs to the HTML spec defining this behaviour (I can't see how it can be done in the fetch or SW spec) |
Thought: look at adaptive formats built from many resources (dash) and come up with a safe strategy there |
This may not be enough. Imagine a request for
…which would give me access to the private data. I realise script isn't requested with ranges, but there may be similar attacks with media? If so, we can ensure that for media using opaque responses, each response must have a first item in the url list that matches the request url. I'm hoping this caters for single-resource media, but also things like DASH that are made up of multiple parts. I use the URL list in attempt to ensure the response has come from the requested location, but allow for redirects. |
Yes. It looks possible to know the private data using media element and the known data in the same origin. Checking the url list looks good to me. |
Action for @jakearchibald: file issues on html spec for handling range requests |
I've begun work on this. HTML PR: whatwg/html#2814 I still need to spec how download-to-disk works, but I'll take that on as part of background fetch. |
Closing this, because the work needs to happen in other specs. |
Say an element makes two ranged requests and receives two responses, and the serviceworker handles both. If the element accepts opaque responses (video), the serviceworker could mix opaque data from different urls, or opaque data with non-opaque data.
@sirdarckcat - could you quickly sum up an attack based on this? My brain's kinda reset and I can't think of anything bad you can do here other than lie to yourself.
+@slightlyoff
The text was updated successfully, but these errors were encountered: