-
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
Foreign fetch vs non-credentialed requests #878
Comments
I think we decided to "live with this" right? How can this be v2? Is that because foreign fetch is somehow v2? |
I thought foreign fetch was v2. |
We did? Does that mean that we're OK breaking no-credentials CORS fetches completely? |
I'm fine with that decision, but at the F2F the conclusion was that it probably would be a good idea to run this by some security people so we don't run into any surprises when/if they later discover that we broke some guarantees around no-credentials CORS fetches. @metromoxie @mikewest: either of you want to weigh in on this? We're trying to figure out what to do about no-credentials CORS requests in the context of foreign fetch. |
Yeah, I also discussed this on the WebAppSec list: https://lists.w3.org/Archives/Public/public-webappsec/2016Jan/thread.html#msg116 (our design has changed a little bit since then, but it's still effectively the same). I did not get as much feedback as I would like though, so asking again here doesn't hurt, but I feel pretty confident with the current approach and I have the feeling I'm generally the most conservative when it comes to the same-origin policy. Also, I don't think we can consider this type of communication at the same level we consider network APIs. Folks are trying to do that with the cache API, and that kind of reasoning just doesn't apply perfectly. This is basically all client-side code talking to each other. |
In our first discussion about this, I was aware that we were leaking some credentials as B's SW was fetched via SW, but I hadn't appreciated that B could turn every no-credential request into a credential request. I'm sure @annevk made this clear at the time, but it didn't sink in. If we decide that no-credential requests are only designed to protect B and not A, this isn't a problem. It's B's cookies that are used after all. |
The reason we have requests without credentials is to simplify the setup for a fetchee to share its data and to make that more common case reasonably safe. They do not protect the fetcher, since the credentials are from the fetchee. |
I vote "live with this" then. I probably made too big a deal of it at the F2F. |
A thing we could add for defense-in-depth is more registration options. Optin for methods, headers, credentials, etc. so you don't have to write JavaScript to filter out the "bad" requests. |
We spoke about that too, but again it's only for B's protection. |
Yes, the ease of writing a foreign fetch service workers. (Note that all of CORS is about fetchee's protection too. Fetchee's protection is not unimportant.) |
I thought allowing B to send credentialed requests for things like fonts hosted on B created a tracking issue. Is this not the case? In fact it seems B could send credentialed requests to C to track the user, which is not something the server could do.
Yes, this is basically what I'm asking for in issue #880. Some basic protections against potentially dangerous requests that you should opt-in to. |
I lean towards "as is," since it really is B foot-gunning itself, although it does seem a bit too easy for a developer to go awry. I was wondering about having separate handler registrations for 'credentialed' and 'non-credentialed' requests, which I think maybe what @wanderview is suggesting. Also, perhaps I'm just confused (or maybe this is orthogonal), but what happens if B returns an opaque, credentialed response from C? That is, A makes a non-credentialed request to B. B's SW's foreign-fetch handler returns an object it earlier fetched from C, with credentials. This seems like a particularly weird relationship, because C thought it was responding to a credentialed request, and A thought it was making a non-credentialed request, and neither one can possible know about what's going on. I'm afraid I'm just confused, though, and this probably doesn't matter. |
@wanderview the moment you allow B to be credentialed you have that problem. And given that existing service workers are credentialed it seems like that will be the common case. @metromoxie it depends on what mode A used. If A used "cors", you'd get a network error. If A used "no-cors", A would just get an opaque response, as it always would in this scenario. |
But this is not something you can do with same-origin service workers today. And letting someone setup a tracker across all sites referencing a third-party font, etc, seems quite bad, no? It doesn't even need an iframe so protections against 3rd party iframes won't work. If we change registration to choose "credentialed" vs "non-credentialed", the worker would not be able to be shared with normal same-origin operations any more. Since we can't trace async operations back to their source event easily we would need to prevent credentialed operations everywhere in the service worker. A little bit more magical would be to spin up a second worker thread for non-credentialed and flip a flag on ServiceWorkerGlobalScope. Any code running in this restricted instance of the service worker would fail credentialed network requests. |
How are you going to prevent that though if you still give the ability to do just that? Seems like irreconcilable goals. And what exactly is the attack model here? If B is used everywhere and wants to track, it can already do so, with or without credentials, and even better the moment we let it run scripts. |
Well, as I understand it, CSS @fontface loads without crediantials. If B is hosting a font, suddenly it can now register a foreign fetch service worker and get a tracking cookie delivered with all those font loads. I guess what you are saying, though, is that since B can run script in the service worker anyway it could just store its own cookie in IDB and send it along in the URL query field. Is that correct? |
Yeah, once you allow script, all bets are off. This is basically turning Now that we've gone back and forth a bit on it though, I could imagine the media having a field day with this once they find out. |
I know that fonts are a main use case, but we could restrict ForeignFetchEvent to just certain types of network requests. If we restricted to xhr/fetch we could still allow people to build progressively enhanced REST APIs. |
I'm happy to discuss further, but at this point I think I either need to see a concrete proposal or talk to you (and others) to further flush out some kind of alternative plan (e.g., a video conference). This doesn't work too well. |
On the other hand, if we want to just "live with it", we should get some feedback from the security community first. |
Sure, if only they could be magically summoned and bring us all the answers 😊 |
Do we also have this same problem when foreign fetches originate in different-(eTLD+1) IFRAMEs while third-party cookies are blocked? |
Third-party cookie blocking is not something that's part of standards so it hasn't really come up. I suspect that when you enable that, you don't get foreign fetch. |
The more I think about this the more I agree with the approach that requires origin A to opt-in to foreign fetch interception via a header or meta tag. But obviously I'm not a security guy, etc. |
https://twitter.com/josh_triplett/status/781482468486488064 long thread, but a lot of concern that an |
The angle being forums that are okay with their users being tracked, but not ddos'd? Hmm. |
I think the concern is about ddosing another third party. |
@annevk Right, DDoS was the big concern. Suppose you have a forum or other site that allows the posting of safe non-active content only, but allows you to embed third-party images. Many sites do allow that, and consider img tags safe. (I agree that they should take more care to avoid tracking, yes.) If someone linked to 100 images in an effort to DoS some other site, that's easy to notice and ban. But someone could link an image or two from a cooperating server, that image could serve a foreign-fetch service worker, and that foreign-fetch service worker could make a large number of requests to third-party sites. And as long as the image itself shows up correctly, it's harder to notice the subtle DDoS via the foreign-fetch service worker (complete with amplification attack). One possible fix would be to require the main first-party site to opt into (or, at least, allow them to opt out of) allowing foreign-fetch service workers for some or all subresource requests via CSP. |
Sure, I understood the attack. Not entirely sure I found it convincing. |
F2F: Between the ddosing worry, and the credentialed thing, should foreign fetch be opt-in by the fetchee? |
Sorry @jakearchibald , do you mean the fetcher (who that makes the fetch)? |
Yes |
I think the main problem with foreign fetch is the third-party cookie problem as I outlined on blink-dev. Safari has a fundamentally different way of dealing with third-party storage that is arguably better for users. If user agents aligned on that, much of foreign fetch would not work well due to it being double-keyed. So we'd need to work that through first and figure out the more fundamental architecture around third-party storage. |
Are there any proposals for supporting double-keying here? I am doubtful. Fundamentally:
These are diametrically opposed. I am having a hard time envisioning a solution that satisfies both goals. From my perspective foreign fetch is a progressive enhancement. It can be present for credentialed requests where the user is willing for 3rd party origins to maintain state about them. It can also be disabled if the user signals they don't want 3rd party origins to maintain state. |
The problem as I said before is that Safari uses double-keying by default for third-party storage (unless there was a first-party visit). As that's a better model than what other browsers deploy, I don't think we should introduce this feature if that forces them to adopt a less a model that's not as great for privacy. I actually think we should adopt their model in Firefox too. |
Why would it force them to do anything? Safari could simply not implement foreign fetch or enable it with similarly double-keyed storage. It would be less effective, but that's already a trade-off they get with 3rd party iframes using IDB, etc. Again, what is the alternative? |
Depending on how sites make use of this and start relying on it, Safari might be forced to adopt other models and other browsers would be constrained from implementing models that are better for privacy. An alternative would be acknowledging that the Safari model is better and gradually move everything to be like that. |
F2F: Need to think about opt-ins and restricting by type. TODO: go through the meeting notes and write up issues. |
For me: write up issue and get a smaller group together to discuss. |
Closing due to removing foreign fetch. |
As currently specified foreign fetch doesn't play together well with non-credentialed requests. In a world without foreign fetch, a website on origin A can fetch something from origin B without credentials, and there is no way (modulo fingerprinting) for B to associate that request with its cookies. If B can intercept the request with foreign fetch this is no longer the case as B itself was fetched with credentials, and can make credentialed requests and access data that was cached using credentials. There are a few options here:
Somehow make it possible for origin B to say "this service worker does not need credentials". In the case of something like the fonts use case this would be done by adding an extra flag to the Link: header that installs the foreign fetch capable service worker. The effect of this flag would be for the service worker to be isolated in effectively its own origin. This origin will never be able to make non-credentialed requests. If a service worker isn't registered with this flag it won't be able to intercept non-credentialed requests.The text was updated successfully, but these errors were encountered: