Giter Site home page Giter Site logo

Comments (27)

annevk avatar annevk commented on August 14, 2024 1

There's two different ways a fetch selects a service worker:

  • Scope-match: used for navigation and workers
  • Use service worker of the environment: used for subresources

This is why <link rel=stylesheet href=...cross-origin...> goes through the document's service worker but <iframe src=...cross-origin...> does not. Now if you use same-origin URLs everywhere and fetch the responses with CORS you can indeed host cross-origin content this way, but it has as much privilege escalation as including a third-party script.

from proposals.

annevk avatar annevk commented on August 14, 2024

How is this less elevated? And why exactly would the third-party fetches from the service worker not be considered to be cross-origin?

(We use a similar pattern for various WHATWG Standards, see e.g., https://fetch.spec.whatwg.org/service-worker.js.)

from proposals.

jackfrankland avatar jackfrankland commented on August 14, 2024

How is this less elevated?

It definitely depends on the circumstances, but for example, if a CMS is being used that allows for custom JS libraries to be added, as is the case for AEM I believe, then someone with privileges for content creation in an organisation could implement this, rather than needing network privileges. I think though, if this type of masking is not wanted in general, then we should remove it if plausible, regardless of its ease of implementation.

And why exactly would the third-party fetches from the service worker not be considered to be cross-origin?

The fetches are considered cross-origin when the service worker makes the request. Once the response is passed on though, it is not considered cross-origin from the perspective of the document making the initial request. This applies to all sub-resource requests, iframe documents, requests within iframes etc.

The WHATWG example doesn't seem to demonstrate a cross-site or cross-origin proxy as far as I can see. It uses a service worker from a different origin as a resource, but it doesn't fetch a resource from a different origin when intercepting requests in the scope https://fetch.spec.whatwg.org/.

The use case I can see for this is to be able to cache third party resources for offline use, but in my opinion, a properly partitioned Foreign Fetch would be better suited for this (if this is a legitimate use case... I'm not saying it should be reimplemented).

from proposals.

annevk avatar annevk commented on August 14, 2024

This applies to all sub-resource requests, iframe documents, requests within iframes etc.

Frames establish browsing contexts and therefore whether a URL goes through a service worker is a different mechanism (equivalent to the top-level document). For those navigations you cannot respond to a same-origin URL with a cross-origin resource; the Fetch Standard prevents that.

(The WHATWG example fetches a bunch of cross-origin resources from resources.whatwg.org. E.g., that's where all the style sheets come from.)

from proposals.

jackfrankland avatar jackfrankland commented on August 14, 2024

Please see the following, showing that the request for the iframe is handled by the service worker (there is no iframe resource on that actual URL, it is being intercepted by the service worker, which requests the iframe from a different site). The script is also intercepted, and you can see it has free script access to the top window. The CSP is default-src 'self'; script-src 'self' 'unsafe-inline'; worker-src 'self';

Firefox:
image

Edge Chromium:
image

I've been quite careful to ensure my testing is accurate, but there's still definitely room for error on my part 🙂

(The WHATWG example fetches a bunch of cross-origin resources from resources.whatwg.org. E.g., that's where all the style sheets come from.)

As far as I can tell, the cross-origin resource requests will not be intercepted by the service worker, because they are not in the scope of the service worker (and can not be).

from proposals.

jackfrankland avatar jackfrankland commented on August 14, 2024

There's two different ways a fetch selects a service worker:

Scope-match: used for navigation and workers
Use service worker of the environment: used for subresources
This is why goes through the document's service worker but <iframe src=...cross-origin...> does not.

Right I understand now, sorry about that, it was a gap in my knowledge that cross origin sub-resources can indeed be intercepted by a service worker registered to the same scope as the document. On the subject of the proposal (but I agree your use case is valid to this), where only same-origin URLs are used...

Now if you use same-origin URLs everywhere and fetch the responses with CORS you can indeed host cross-origin content this way, but it has as much privilege escalation as including a third-party script.

I would argue that this does give higher privileges than just a third-party script being loaded on the first-party. Sub-resources and iframes can be loaded by the third-party script, but the browser is always aware that these resources are cross-origin, and can implement restrictions accordingly. As demonstrated above, CSP is bypassed here; there must be a reason why scripts are treated differently to frames, images, fonts etc. according to CSP. In terms of privacy, I'd like to see further progress made at some point to restricting third-party scripts' capabilities - a service worker acting as a cross-site proxy may work against that progress.

Also, the registration of the service worker needs only to happen on one page of the first party site. On subsequent navigations, a proxied iframe only needs to be present in the document for the third party to be loaded under the guise of first party, rather than an explicit script.

from proposals.

jackfrankland avatar jackfrankland commented on August 14, 2024

To still allow your use case, the proposal could be amended to something like:

A fetch made within a service worker fetch handler must match the origin of the event.request

from proposals.

annevk avatar annevk commented on August 14, 2024

I don't really see how this relates to CSP. If you want CSP to be enforced and use service workers, you also need to set it for the service worker.

from proposals.

jackfrankland avatar jackfrankland commented on August 14, 2024

I wasn't intending for CSP to be seen as very relevant to the discussion, I was just using it as an argument for why a third party being fully masked as first party is a privilege escalation over a third-party script being loaded on the first party.

from proposals.

jackfrankland avatar jackfrankland commented on August 14, 2024

I've updated the proposal in the issue post above.

@annevk would be good to know your thoughts on this - do you think there are legitimate use cases to allow a service worker to fetch a resource from a site / origin that is different to the resource being requested by the document?

from proposals.

annevk avatar annevk commented on August 14, 2024

Yeah, if you include an image from elsewhere on the web it would be annoying if that did not work offline. Or in case of the WHATWG, if our style sheets stopped working.

A fetch made within a Service Worker fetch handler must match the site (or origin?) of the request it is handling.

I don't see how you can realistically enforce this. Stack inspection is not in the cards and it wouldn't even work if you use a storage facility to launder things.

from proposals.

jackfrankland avatar jackfrankland commented on August 14, 2024

Thanks. I suppose looking at it from a different angle, the goal of this proposal is: to ensure that the document (and its CSP) can trust that the origin of a resource is correct, so it can implement security and privacy measures effectively.

Currently, Service Workers are able to supplant responses from different origins to the request, with the document behaving no differently. I personally think an attempt should be made to prevent this. I guess the first thing is to see if anyone agrees with me on this.

My first thought was to prevent cross-site fetches inside the Service Worker. As you pointed out, a Service Worker can indeed handle resource requests for different sites. To handle this, I thought maybe there would be a way within the Service Worker to ensure any fetches that occurred in a fetch handler matched the origin of the request. I definitely see now that this isn't feasible, nor would it prevent responding with a cached version of a response from a different origin.

My last thoughts on how to reach the goal would be either one of two solutions:

  1. The origin of the Response passed in to FetchEvent.respondWith must match the origin of the FetchEvent request. This allows matching cached responses to be passed too, assuming the response url remains intact, but not handcrafted responses.
  2. The document uses the url/origin from the propagated Response, rather than the one from the request.

from proposals.

annevk avatar annevk commented on August 14, 2024

Unless you deploy CSP for all your environments on a given origin, including service workers, it won't be able to do its job. And as the document can come from a service worker, including CSP headers, if you cannot trust the service worker, you cannot trust the document.

from proposals.

jackfrankland avatar jackfrankland commented on August 14, 2024

I still see merit in the user agent making as much effort as it can to ensure origins are correct for resources. I think this would lessen the need to trust the service worker, as it wouldn't be able to supplant a resource of one origin with one of another. What need is there to give it the ability to respond to resources from different origins to the request, or handcrafted responses?

from proposals.

annevk avatar annevk commented on August 14, 2024

Even without a service worker, how do you ensure a blob URL image is actually same-origin? (If your answer is CSP, the answer would be the same for the service worker.)

from proposals.

jackfrankland avatar jackfrankland commented on August 14, 2024

In the scenario in the original post, there's a very good chance that a CSP won't exist for the service worker. In other scenarios, a CSP isn't granular enough to prevent the service worker from responding to a first party request with a third party resource, if there is also a need for the service worker to fetch and cache third party resources. I am also not coming at this from the angle of security that the first party implements, but rather privacy for the user, regardless of whether the first party has lax policies for whatever reason. I hope to see user agent controlled restrictions on what a third party script can do on the first party also, beyond CSP's current capabilities (to, say, disallow a third party script creating a first party blob url).

Disregarding these other things for a moment, the question still remains: is there a legitimate use case for allowing a service worker to fetch a resource from a different origin to the request, or synthesise a response for that request? And if so, is there any reason why the origin of the propagated resource on the document shouldn't be considered as the true origin?

from proposals.

annevk avatar annevk commented on August 14, 2024

I don't think you can disregard those other things, since it's not clear to me that what you're suggesting is actually feasible.

And also, how would you meaningfully prevent such a thing or find out the true origin of a response?

from proposals.

jackfrankland avatar jackfrankland commented on August 14, 2024

If the origin of response.url in fetchEvent.respondWith(responsePromise) does not match the origin of fetchEvent.request.url, then an error could be thrown.

If that doesn't seem like a good idea, then I think this discussion is relevant to how a response from a service worker should be treated: https://bugzilla.mozilla.org/show_bug.cgi?id=1222008. Please note I haven't read through all of it, but from what I understand, there is already a concept of treating the response in a similar manner to a redirect.

from proposals.

annevk avatar annevk commented on August 14, 2024

@jackfrankland I don't see how that helps. What prevents the service worker from creating a synthetic response containing the bytes of the other origin?

from proposals.

annevk avatar annevk commented on August 14, 2024

(If you follow the link that bug you'll find I've made the change to Fetch. I was one of the people who designed how Fetch and Service Workers interoperate. I don't want to make an argument from authority, but I do feel like do not need to read up on this.)

from proposals.

jackfrankland avatar jackfrankland commented on August 14, 2024

I was definitely aware of that already, and didn't mean for it to look like I was referencing something you should need to read, but rather referencing a previous discussion that seems to be focused around a similar concept of treating the service worker response as a redirect: there's much more chance that I'm wrong about that being feasible.

What prevents the service worker from creating a synthetic response containing the bytes of the other origin?

The url of the synthetic response wouldn't match the origin of the request.

from proposals.

annevk avatar annevk commented on August 14, 2024

Okay, but in OP you were talking about the request URL being same-origin, e.g., /third-party/something and the service worker mapping that to another origin. A synthetic response is same-origin with the service worker.

But generally disallowing that would prevent redirects across CDNs and such, which seems bad. And also imbues more authority into the document than it actually has, as the service worker could just rewrite it.

from proposals.

jackfrankland avatar jackfrankland commented on August 14, 2024

Okay, but in OP you were talking about the request URL being same-origin, e.g., /third-party/something and the service worker mapping that to another origin. A synthetic response is same-origin with the service worker.

Yeah, the first option as a solution would disallow synthetic responses, by a different means to origin check if necessary - I naively thought that the origin is taken from the url, which in that case would be an empty string.

But generally disallowing that would prevent redirects across CDNs and such, which seems bad. And also imbues more authority into the document than it actually has, as the service worker could just rewrite it.

Are you saying that the use case for allowing a service worker to fetch a resource from a different origin is to offload that logic from the document, so it doesn't need to care about different origins when fetching resources? In case there's confusion, by true origin I mean only the origin of the network request made by the client, not origins further upstream.

from proposals.

johnwilander avatar johnwilander commented on August 14, 2024

In the case of WebKit, we partition ServiceWorkers. Is that something that would change your analysis, Jack?

from proposals.

jackfrankland avatar jackfrankland commented on August 14, 2024

I don't believe so, if I'm understanding you correctly.

Essentially, I find it odd that a request can be made for a same-origin resource or iframe, and that the response can be from a different origin, while affording it the same privacy rules on the document as if it were same-origin. In this way, the functionality is almost equivalent to a server-side proxy, but with arguably an easier install process. This issue also assumes that it is generally undesirable for trackers to be more prevalently integrated into first party origins via server-side proxies; but there's not much a user agent can do about that (while it can do something about this).

It could be argued that from a tracking point of view, a third party script is easily included on the first party and it can already do a lot. But, there are other proposals that aim to limit the ability of third party scripts - and perhaps having this service worker mechanism available as an option will allow third parties to circumvent these efforts.

I would be interested to hear if you share this view in any way, and very happy to be told I am off-base in my concerns :)

from proposals.

jackfrankland avatar jackfrankland commented on August 14, 2024

Just thinking aloud here... is it possible for a tracker to have their service worker installed onto a network of sites, and for the installation status of the service worker to be used as a tracking vector as part of a series of navigation redirections? With requests to the cross-origin tracker allowed within the service worker, information about this status can easily be sent too. Because the origins of the navigation requests are not the tracker, it can more easily avoid being included in the tracker list.

from proposals.

TanviHacks avatar TanviHacks commented on August 14, 2024

@jackfrankland and @annevk - Would you like to keep this proposal open? I know user agents are moving towards partitioning Services Workers. Is there more to discuss here? Thanks!

from proposals.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.