privacycg / storage-access

The Storage Access API
https://privacycg.github.io/storage-access/
209 stars 27 forks source link

Opt-in mechanism for shared storage access #17

Closed johnwilander closed 3 years ago

johnwilander commented 4 years ago

We've discussed in both https://github.com/privacycg/storage-access/issues/3 and https://github.com/privacycg/storage-access/issues/14 what to do about sibling iframes and nested iframes from the same third-party that is being granted storage access.

In a discussion with @englehardt and @ehsan elsewhere, the following exchange of thoughts happened:

[Person 1] I wonder if instead we can add a notifyMeOfStorageAccess event?

[Person 2] Could work. Or even a proactive document.optInToGrantedStorageAccess(). Maybe that's what we need. Per frame by default but all frames can explicitly say they want in if one gets access.

[Person 1] Yeah, basically some way for frames to register that they expect and desire for their access to be swapped out or unblocked.

[Person 2] Excellent. We should hash this out on GitHub.

Thoughts?

jackfrankland commented 4 years ago

I'd just like to highlight the method that I use currently that allows nested/siblings iframes to share state completely, which is maybe similar to what is being alluded to as a possibility in https://github.com/privacycg/storage-access/issues/14

  1. publisher.com embeds hidden third-party.com iframe, that acts as the master
  2. publisher.com embeds several other visible third-party.com iframes
  3. the visible iframes register themselves to the master, giving it full control over their documents
  4. all scripts, state, storage access and requests are handled by the master

This might be an extreme example, but you don't have to have a hidden master iframe. One sibling could be promoted for example to handle the storage access, with the others subscribing to it.

Brandr0id commented 4 years ago

Thinking about this a bit further I think I would be concerned about adding complexity to notify sibling frames or ensuring they opt in, in the right order/timing to ensure they are included in the extended access (or maintaining that state to extend to late calls of optInToGrantedStorageAccess). The event to notify of storage access does sound interesting as it may bake a common usage pattern into the browser rather than have developer code broadcast to their siblings that access is now granted. I'm not sure it would be a suitable replacement for per-page access being granted though. Perhaps a way to mitigate the concerns about state changing under the frames?

The way the API exists today is kind of nice as it doesn't add a tonne of complexity for developers. They can check if they have access while also requesting access during an interactive event such as clicking a button.

Given there are methods like jackfrankland mentioned for sibling frames to communicate with each other it only takes one frame having access for them to all effectively have access if enough effort and code is put into it. However limiting the scope to per frame does limit an implementers ability to persist grants on subsequent page loads (for example within the same browsing session) - https://github.com/privacycg/storage-access/issues/2.

I think this per-frame limitation also adds to the complexity of developers trying to use the API. They would need to manage or use the events/opt in proposed in this thread or pass messages between the frame that was granted to "ferry" access over to their other frames. Whereas today multiple embeds by the same 3p origin would start out in a logged out state (no storage). One click/user-gesture and a given frame has access. That frame could then broadcast to its siblings to then update their UX to re-fetch state and now the whole page looks to be working. If things were limited to per-frame then the sibling frames would then have to request that the one frame that has access requests the info and broadcasts it out.

A slight aside but while it's top of mind, implementation details may be slightly tricky for Cookies to limit per-frame within Chromium code as-is. Current cookie scope/limitations are not enlightened about details of the document they came from and happen in a separate process (Network Service). Currently details like the origin(s) that host/request access are available but there's no direct link/reading a property from the Document to see if access should be given or not. It's not to say that the concept of a document identifier can't be added in there, but it's not really a concept that naturally aligns with Cookies as they are today. All other existing restrictions are in terms of top-frame-origin, requesting-origin. It would be nice to maintain that consistency in addition to other reasons to allow per-page scope.

johnwilander commented 4 years ago

Thinking about this a bit further I think I would be concerned about adding complexity to notify sibling frames or ensuring they opt in, in the right order/timing to ensure they are included in the extended access (or maintaining that state to extend to late calls of optInToGrantedStorageAccess). The event to notify of storage access does sound interesting as it may bake a common usage pattern into the browser rather than have developer code broadcast to their siblings that access is now granted. I'm not sure it would be a suitable replacement for per-page access being granted though. Perhaps a way to mitigate the concerns about state changing under the frames?

The way the API exists today is kind of nice as it doesn't add a tonne of complexity for developers. They can check if they have access while also requesting access during an interactive event such as clicking a button.

Given there are methods like jackfrankland mentioned for sibling frames to communicate with each other it only takes one frame having access for them to all effectively have access if enough effort and code is put into it. However limiting the scope to per frame does limit an implementers ability to persist grants on subsequent page loads (for example within the same browsing session) - #2.

I think this per-frame limitation also adds to the complexity of developers trying to use the API. They would need to manage or use the events/opt in proposed in this thread or pass messages between the frame that was granted to "ferry" access over to their other frames. Whereas today multiple embeds by the same 3p origin would start out in a logged out state (no storage). One click/user-gesture and a given frame has access. That frame could then broadcast to its siblings to then update their UX to re-fetch state and now the whole page looks to be working. If things were limited to per-frame then the sibling frames would then have to request that the one frame that has access requests the info and broadcasts it out.

A slight aside but while it's top of mind, implementation details may be slightly tricky for Cookies to limit per-frame within Chromium code as-is. Current cookie scope/limitations are not enlightened about details of the document they came from and happen in a separate process (Network Service). Currently details like the origin(s) that host/request access are available but there's no direct link/reading a property from the Document to see if access should be given or not. It's not to say that the concept of a document identifier can't be added in there, but it's not really a concept that naturally aligns with Cookies as they are today. All other existing restrictions are in terms of top-frame-origin, requesting-origin. It would be nice to maintain that consistency in addition to other reasons to allow per-page scope.

It may be that I'm tired, but I'd like to see if we can summarize what you're saying. 🙂

  1. I'm hearing the "the way the API exists today is kind of nice" but it exists in two slightly different versions (Safari and Firefox). Do you think both are nice on some higher level or is it a specific implementation you think is nice?

  2. You say iframes can talk to each other and forward granted storage access through messages. But you also seem to think that that's not good for developers. Is this an argument for an opt-in mechanism or for "access to all sibling iframes" or for page-wide access including Fetch and tracking pixels?

  3. The limitation in Chromium sounds like it might not only be for a per-frame approach but possibly also for "access to all sibling iframes" and per-page access. Can you explain a little further, please?

Brandr0id commented 4 years ago

It may be that I'm tired, but I'd like to see if we can summarize what you're saying. 🙂

Thanks!

I'm hearing the "the way the API exists today is kind of nice" but it exists in two slightly different versions (Safari and Firefox). Do you think both are nice on some higher level or is it a specific implementation you think is nice?

I was specifically referencing on a higher level here. There are only two methods to worry about and potentially even only 1 (requestStorageAccess) depending on how you code your site. Although thinking a bit further there is also a nice simplicity in the FireFox impl that as soon as your request access for your third party origin within the top level origin storage access restrictions for that pair just unblocks from that point in time. It's a fairly easy concept for developers to work with.

You say iframes can talk to each other and forward granted storage access through messages. But you also seem to think that that's not good for developers. Is this an argument for an opt-in mechanism or for "access to all sibling iframes" or for page-wide access including Fetch and tracking pixels?

I'd say mostly I struggle to see the meaningful impact for users privacy we provide at the cost of complexity for website developers and implementers by limiting this to per-frame. Once one frame is unblocked developers could work around this with complexity in their code but that doesn't seem beneficial to move in that direction.

The limitation in Chromium sounds like it might not only be for a per-frame approach but possibly also for "access to all sibling iframes" and per-page access. Can you explain a little further, please?

I'd say that's a fair assessment. The current arch model aligns well with the FireFox impl in that using other factors to scope the duration of the grant/permission for storage access matches the cookie notion of access being a pair of origins (top-level/thirdparty). After some event X that access is removed. With the current FireFox model that event would be 24hrs or end of browser-session which ever is sooner, in most cases. However this could be changed to last tab of top-level-origin closed and other interesting ideas. This sort of relates to thinking in the Permissions space for how to scope things like geolocation permissions as well...but I don't want to get too far off topic :).

All this isn't to say the other scopes aren't possible, just that the more drilled down we go (per-frame and sibling frames being the more challenging) we have to shoehorn more concepts/data that isn't natural to the grants and CookieStore that may not align well with Cookies. Perhaps they do more so with other storage types like localStorage that have a direct link to the Document in question when accessed.

johannhof commented 3 years ago

Correct me if I'm wrong but having per-page storage access and tracking an event API in #55 we can probably close this issue.