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
Service workers allow for more responses to be executed as script #1509
Comments
Possible solutions: Add the request method onto the response, then update the HTML spec so APIs that accept no-cors requests reject if the response is no-cors and the request method is not Limit cross origin no-cors requests to Which APIs can currently make no-cors non-navigation POST requests? If that's the only one, we could make |
|
Right, but I'm saying we could stop that (if usage is low enough). |
CSP's reporter is also POST and no-cors. I imagine other reporters are the same. |
Although there are a few APIs that send no-cors POST requests, none of them seem to use the response body. Around the same point in the spec as CORB (or even, part of CORB), if the request is no-cors & non-GET, the body of the response can be removed. The fetch will still succeed, and specs will still be able to look at the status code, but |
What happens if such a POST gets a 301/302/303? Still blocked somehow? This does seem quite nice on the face of it. |
I guess you mean if the no-cors request leaves the origin but is redirected back to the origin for the final response? |
That's a good twist, but a redirect to a POST with one of those response statuses will also change the request method to GET. |
/cc @anforowicz @csreis in case they had considered something like this in the context of CORB. |
Our general goal with CORB was to only let cross-origin responses into the renderer process if they could be legitimately used as subresources (e.g., in script tags, image tags, etc), or if they were allowed via CORS. The blocking logic didn't care how the renderer process actually asked for the response (e.g., via ServiceWorker vs script tag), since a compromised renderer could claim to use whatever request type would let it get the most data. Thus, CORB blocks things like HTML, XML, and JSON whether a ServiceWorker is asking or not. It does sound like this trick would let an origin try to run more things as script than usual, so I'm happy to see you all talking about ways to address it. I don't have strong feelings about how or where in the spec it goes, though. I only suggest that you avoid having the CORB part of the spec depend on how the content was requested (e.g., whether it was from a ServiceWorker), since that can be forged. |
Fwiw, that wouldn't be the condition here. The condition would be "is the response opaque, and was the request method not-GET?" The condition wouldn't be dependent on the service worker at all. Although, I realise it's still checking aspects of the request. It doesn't need to be in the same bit of the spec as CORB of course, but it would seem a shame to copy & paste a lot of the prose if it's 90% the same. |
So, how does the change in behavior look from the CORB perspective? Is it something like this?:
I think this should work. CORB only needs to allow legacy no-cors requests (images, scripts, stylesheets, etc.) and AFAIK these should always be GET requests. So, extending CORB heuristics to cover all non-GET requests makes sense from this perspective (no risk of breaking existing behavior + more requests protected by CORB = seems like a desirable change to me). |
Oh, one more question - will this proposal be testable via WPT? AFAIK there are no web APIs for reading the response body associated with beacon and/or reporting POST requests, right? If the proposal is non-testable via WPT, then should it be in a non-normative part of the spec? |
Exactly.
Yeah, you can make no-cors POST requests using
|
I would prefer we network error for this instead of using CORB. I'm not convinced CORB as-is is the right long term solution for opaque responses. |
APIs are making no-cors POST requests. I'm worried about compatibility issues if those start failing. From what I've seen, they're fire-and-forget, but I don't know if they're all like that. |
Perhaps adding a |
Unfortunately it affects |
I guess we could look at the numbers |
Adding a metric for |
My memory is a bit flakey here so correct me if I'm wrong: if an opaque response redirects, the response is always opaque right? CSP uses "error" for redirect. I guess we would enforce that for all non-GET no-cors requests. If we're going the CORB-style route, I guess we could follow redirects by default, but create a new response tainting of " |
Yeah, you're not supposed to be able to recover from opaque. |
@mikewest @annevk does this look right to you? https://bugs.chromium.org/p/chromium/issues/detail?id=1072350 |
Yeah, thanks. |
Where does this issue stand? |
It seems that per https://chromestatus.com/metrics/feature/timeline/popularity/3316 there's an unusually high number of responses to which this is applicable. It's not clear to me however that making these a network error would end up breaking things as they might mostly be beacon requests of sorts. I guess nobody did what @mikewest suggested in https://bugs.chromium.org/p/chromium/issues/detail?id=1072350#c27? |
Instead of blocking the requests at the |
We could I suppose. That would require storing an additional bit on the response, right? How would that work with the Cache API? |
The bit would have to be stored along with the response so it could be reproduced when read back out. In chromium we already store it for other reasons: |
I guess this doesn't help with the "custom Accept header" from the original post above, though? |
Yeah, it wouldn't help with the couple of headers the attacker gets to control, but method is a lot more significant and it seems somewhat reasonable to declare the headers out-of-scope. |
Before service workers you could only execute as script what
<script src>
allows you to target. After service workers any response a service worker can obtain, can be given to a<script>
. E.g., consider a response to a request whose method isPOST
or one that has a customAccept
header value.Should we enshrine this as another weakening of the same-origin policy or do something about it?
Credit: 1lastBr3ath.
The text was updated successfully, but these errors were encountered: