-
Notifications
You must be signed in to change notification settings - Fork 349
Consider preserving destination on new Request(request)
#717
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
Comments
1 is essentially why we don't do this. See also #521. This functionality would allow an advanced XSS attack to bypass CSP and serve the response of an image (which might have "unsafe domains" safelisted) as a script. |
The only way to make this work is if we guard the response (make it opaque (though maybe slightly less than opaque is okay) + special destination marker) so it can only be used for its intended purpose and cannot be read from otherwise. |
I find it surprising that currently we just nullify the destination in such cases, since it is problematic for CSP, as @wanderview stated. In any case, would be great to be able to maintain the destination, at the price of opaque responses. (maybe an opt-in is required, for cases where people want to manipulate the response and don't care about the destination?) |
It's problematic for CSP if you don't nullify it, as I've explained many times on many threads... If you pass the |
I understand. At the same time you stated above that:
Which seemed like a way forward
If there's already a way to get around the destination nullification then that's great. Can you point me at an example? |
Sorry, I was mistaken, the only way is to not invoke A guarded opaque response has always been presented as a way forward, but nobody has been willing to put in the work. |
Does that also work conditionally? e.g. have the fetch event handler |
@yoavweiss I think this should work, but I haven't tested: onfetch = e => {
if (e.request.destination !== "image") {
// Do things here.
}
} |
Yeah, if that works, that could be a way forward for people to tackle this use-case. |
I think this went off track a little... The confusion was not that images shouldn't be handled by the service worker (they should in my use case), it was that the service worker is subject to connect-src for all requests it does manage. It may well be the correct way for the fetch to behave, but it was a struggle for me (I failed until helped by Jake) to find any mention of it in the fetch spec/documentation. |
@qubyte basically once you use There's an open question here if you would be okay with opting into getting a response you can store in the Cache API and such, but otherwise only use for |
Yup, I understand this now, and it makes sense (at least as a default). My concern is the mixture of it not being so obvious and the difficulty in discovering why (thus my post). |
My gut feeling is that requiring |
Requiring |
Its unfortunate, though, if I have to allow my service worker script to hit any cross-origin resource when I know my site only makes cross-origin requests for a particular destination type. It basically means you can't use CSP to lock down your SW script if you have any cross-origin resources you need to handle with respondWith(). |
Maybe a stupid idea, but could we:
This would let a service worker use a CSP like: default-src self; image-src *; connect-src use-original-destination; This would give the service worker a more restrictive policy than what it would need otherwise: default-src self; connect-src *; And it would not open up the XSS for pages unless they opt-in to the "use-original-destination" policy. |
@annevk pointed out in IRC that this still would not help since the service worker controls the page and can arrange for any destination request it wants. So it would be a false sense of protection. I'll leave this open for now since others seemed interested, but I'm mostly convinced its WONTFIX now. |
Closing this given the lack of further input. The only way to do this is creating a new kind of response and that'd be quite involved for not that much benefit. |
Consider the situation described in this blog post:
https://qubyte.codes/blog/content-security-policy-and-service-workers
Essentially a site has set a CSP policy of
default-src self; img-src *
on all its served resources. The intent is to restrict cross-origin resource loads to only images.This works on a normal page, but does not work when the CSP is applied to the service worker script. The service worker script does
fetch(evt.request)
which triggers a network request with an empty string destination. This in turn causes the CSP check to fall back to default-src and fail.I think we should consider preserving the destination when an existing Request is passed as the constructor input. We would only clear the destination if any of the init params are passed to alter the Request. So basically another thing to sanitize under step 14 in:
https://fetch.spec.whatwg.org/#dom-request
This would allow the service worker to have a CSP policy like
default-src self; img-src *
and perform pass through fetch requests for images. It effectively expresses that the service worker is allowed to perform cross-origin network requests on behalf of the browser only for images. Only the browser can mint destination "image" requests.The risks of doing this seem to be:
I'm not sure how bad these risks are. It just seems unfortunate that we effectively require service workers with pass-through fetch handlers like this to disable their CSP protections in the service worker. Effectively the site has to let their service worker fetch() any cross-origin resources if it wants to support pass-through fetch of a specific thing like cross-origin images.
The text was updated successfully, but these errors were encountered: