-
Notifications
You must be signed in to change notification settings - Fork 27
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
How does storage access interact with Dedicated, Shared and Service Workers? #157
Comments
cc @DCtheTall |
@wanderview do you happen to have any thoughts on this? Anyone else come to mind who may have an opinion here? :) |
Copying the "has storage access" bit from the document that creates the shared worker seems the easiest, but it also creates a race that people tried to avoid when designing shared workers. @smaug---- @wanderview @hiroshige-g @gterzian @elkurin @domenic your input would be much appreciated! |
I would expect at least different SharedWorkers to be created depending on whether one has storage access when creating it. Not sure about ServiceWorkers |
Hmm, why would you expect that? The partition does not change and |
Because of https://privacycg.github.io/storage-access/#storage "A future revision of this API might impact other client-side state" |
In principle any permission a document connected to the SharedWorker is accessible to the SharedWorker via postMessage(). So I think inheriting the access bit is somewhat reasonable. In theory SAA grants storage access in a semi-persistent way (for some time period). So the idea you would have one A->B window with access and another A->B without access both connected to the same B SharedWorker seems to only affect niche use cases. Like when first getting access or it expiring. Maybe rather than inheriting it should look for semi-persistent permission when creating the SharedWorker. Look at the SW's storage key to determine if a permission grant exists or not. This functions the same as inheriting in that use case, but might be a bit more predictable for devs. Its possible I am missing context and misunderstood, though. |
We have per-document grants somewhat intentionally so inheriting from something more global feels wrong. @arturjanc I think the threat analysis for Storage Access didn't cover workers, but maybe it should? Would be helpful here. |
Sorry, I was not aware of the per-document restriction. If that is the case, how is SharedWorker different from two documents connected via BroadcastChannel? That would seem to argue not to inherit? |
I suppose we could add some kind of |
Hmm given the back and forth here I wonder if we should highlight this for the SAA graduation discussion at TPAC! |
My two cents: There are two cases that we can think about: now and eventually. @smaug---- 's comments seem to be in the "eventually" case, and I think are based on the what seems natural to me: inherit the partition of the Document on creation. (correct me if I'm wrong). However, I do see potential security benefit of forcing the worker to explicitly request storage access before having unpartitioned cookies, although I haven't thought it through yet. For the "now" case, we are more flexible. The spec currently dictates cookie-only, however it seems possible to skip straight to the "eventually" case since this seems different than the existing discussion of Storage and Storage Access. |
Any thoughts on dedicated workers? @cfredric and I got a bug report that Chrome currently isn't unblocking fetches done in those, while Safari is. I don't think this is something that we're currently specifying, although we probably should (feels like part of cookie layering though). Overall it seems non-controversial to say that if the context that spawned the dedicated worker had storage access, it should propagate to the worker. What about existing workers though, should these be "upgraded" once their existing document gets storage access? |
My intuition is no- having a worker change network partitions mid-execution due to no action of its own sounds apt to cause more confusion than it is worth. |
It's somewhat bad, as we don't propagate any other state that way currently, except for I'm not sure what to do about existing workers. If we don't make those work we encourage sites to instantiate workers after getting storage access, which makes them targetable through XSLeaks (using global resource exhaustion). For shared/service workers, is there a test so we can see what implementations do today? I think ideally for those we require an API call that only works if permission was already granted for the relevant permission key. |
A requestStorageAccess variant for shared/service workers seems interesting off-hand, though I wonder if it's then worth punting this on the next SAA iterations and just declaring that we don't support these two worker types in the initial version. |
Another idea: We could solve the "existing worker" problem by also requiring dedicated workers to always call an rSA like API to get storage access, does that make sense? |
Yeah, that could work. |
I haven't kept up with all the latest SAA changes, but my previous understanding was that the cookie grant was persistent. So that a reload of an iframe or the next load in a new tab will have cookies. Is that still the case? (If not, maybe ignore the following...) If so, I think there might be some weirdness with service workers here. An iframe is intended to get the 1P cookies on reload, but if its intercepted by a service worker FetchEvent the SW will not get the 1P cookies. So a service worker doing Also, we had some discussion in privacycg about applying the cookie grant from SAA to bounce tracking mitigations checks. These checks are implicitly happening on navigations outside the context of where SAA was originally called. (There was some light head nodding that this was ok, but certainly not settled.) I wonder if by trying to forcibly exclude workers we are in some way creating an inconsistency and extra complexity in relation to the cookie permission grants here. |
It's not persistent. You'd have to call We could perhaps forward some of the document's storage access state through the request and the request clone, but you'll end up with some amount of weirdness with multiple documents in different storage access states consuming the response. Seems unavoidable. |
It would still be good to have test coverage and find out what implementations do today. What makes some sense to me:
|
These are not automated tests, but you can play around with cross site SharedWorkers on cors-communication-a.glitch.me and cors-communication-b.glitch.me. From my testing, this is what browsers seem to do today: ChromeVersion 120.0.6068.0 EdgeVersion 118.0.2088.46 In version 120.0.2160.0 however, the behaviour is now on par with the other browsers. SharedWorkers are partitioned regardless of any SafariTechnology Preview Release 180 (Safari 17.4, WebKit 19618.1.1.2) FirefoxNightly 120.0a1 (2023-10-14) OperaVersion 103.0.4928.26 |
@jespertheend this issue is not about whether they get partitioned or not. They should be partitioned. This is about what kind of cookies they get. (In Safari (and WebKit) you need a top-level visit to any cross-site site for |
@annevk Ah I see, that makes sense now 😅 edit: Seems |
This aligns with what I'd like to happen, @arichiv @DCtheTall any concerns? |
Also @cfredric ^ |
I agree with what Anne laid out here, #157 (comment), but am not too certain about the engineering complexity. I'll have to either talk to someone else about it or do some digging to be 100% certain :) |
Agreed, unless there's a compelling case for another approach this makes things simpler.
Agreed, this would be too hard to reason about as the worker pools would then be split.
Agreed
Agreed, Chrome is discussing this now re: https://arichiv.github.io/saa-non-cookie-storage/. The debate is whether first-party Shared Workers should be accessible off of the requestStorageAccess handle returned to a third-party iframe and/or if third-party Shared Workers should just have a requestStorageAccess method of their own to use. The sticking point of that discussion centers on first-party Shared Workers having access to SameSite=Strict cookies. |
Odd inconsistency if dedicated workers do inherit but shared workers for example don't. inconsistencies tend to bite us later. |
If we push for consistency across workers, I think it makes more sense to have dedicated workers not inherit as well. Rather than having shared and service workers inherit. |
Hmm I like the inheritance for dedicated workers though, it kind of makes sense and web sites are already using this. |
This API allows a third-party to break out of storage partitioning, but not the concept of party itself. First-party SharedWorkers have access to SameSite=Strict cookies, so we cannot allow access. There is discussion about allowing access to requestStorageAccess inside SharedWorkers instead: privacycg/storage-access#157
Just to verify if I understood what's been discussed here about Service Workers, is the intention to not expose Service Worker after calling rSA? The use case that we have is that on a top level site like stackblitz.com we embed an iframe on a different domain webcontainer.io which then registers a SW. Since Chrome is phasing out third-party cookies it means that we wouldn't be able to register a SW anymore in the cross-site webcontainer.io frame. There are ways to solve this like using a RWS (Related Website Set). However, a RWS becomes a bit tricky for our WebContainer API users because they would be embedding a cross-site frame to domains other than stackblitz.com, for example angular.dev. Phasing out third-party cookies also means breaking sites like the Angular docs. angular.dev could be added to the same RWS as stackblitz.com and webcontainer.io but this wouldn’t scale to all of our WebContainer API users. Alternatively, angular.dev could do their own RWS submission and use a separate As a refresher, to submit a RWS such as angular.dev +
Which basically means that for Angular they would need their own preview domain, e.g. angular-webcontainer-api.io. And we'd need that for every user that uses the WebContainer API and relies on previews. Another option would be to have them setup a same site preview domain, like So I think being able to allow SW via rSA would be really great, or by any other means. What we are basically looking for is any way (could be a combination of headers, web API, user interaction etc…) to be allowed to install our SW. |
There are plans to add Shared Workers via rSA, could that help? https://privacycg.github.io/saa-non-cookie-storage/shared-workers.html I don't think we have a clean way to resolve the history sniffing or cache poisoning concerns so the path for Service Workers via rSA is still blocked. |
Hm no, Shared Workers won't help in our case cause we rely on Service Workers for our networking stack within WebContainer. |
Just to clarify, service workers are permitted in the cross-site iframe, but they will be in partitioned storage. |
@wanderview It hasn't been our experience nor the ones from the wordpress-playground folks (they have a detailed comment there: WordPress/wordpress-playground#87 (comment)). When third party cookies are blocked, service workers were also disabled. Or are you saying that this could be a bug in Chrome? |
We added this somewhat recently. I just tested quickly by loaded my blog in an iframe: Looks like this was fixed in M118: https://chromiumdash.appspot.com/commit/e83ad48b7de16798e682a50ab68f5fcb3f09b3f9 |
Thanks so much for the clarification @wanderview. Hearing this is a huge relief and we thought that we had to do a whole dance with RWS, domains, or proxies to get this to work. Big thanks to Steven I suppose for fixing this issue 🙏 🙏 🙏 |
If a Shared Worker makes a network request, can it ever consider storage access to include cross-site cookies?
@annevk sketched out the following scenario that might make this tricky:
We have two tabs A1 and A2. A1 embeds cross-site B1 and A2 embeds cross-site B2.
B1 requests and is granted storage access, but B2 does not and thus is still fully partitioned, including its cookies.
B1 and B2 now create the same SharedWorker. On that SharedWorker, does the environment have storage access? Depending on a race it could either have been created by B1 or B2. When it makes a network fetch that is observable by both B1 and B2.
The text was updated successfully, but these errors were encountered: