privacycg / storage-access

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

API Integration with Permissions Policy #12

Closed Brandr0id closed 3 years ago

Brandr0id commented 4 years ago

This was mentioned in https://github.com/privacycg/storage-access/issues/10 but would it be useful to call out integration with a Feature Policy in addition to the sandbox token to control access to the API?

Perhaps defining this as a "storage-access-api" feature w.r.t this.

For reference: https://w3c.github.io/webappsec-feature-policy/ https://github.com/w3c/webappsec-feature-policy/blob/master/features.md

michael-oneill commented 4 years ago

I agree.

In Europe and other places it is incumbent on the site to ensure users have given consent to all storage use other than that for specifically exempted purposes. This also applies to embedded third-party cookies and other storage, confirmed by the Planet49 CJEU ruling.

It follows that top level contexts need to be able gate the ability of third-parties to cause a confusing prompt, they might inform via their own UI the user of the identities and data processing purposes of known third-parties but they need to stop random prompts from other that might end up being there.

If there were a feature policy directive then this could also be used to collect third-party domains and other identifying information from the top-level then the browser can display a combined prompt to the user with all the information to enable the required "freely given, specific, informed and unambiguous" consent, only once. Otherwise random prompts becomes just more annoying, confusing and opaque intrusions.

othermaciej commented 4 years ago

I mentioned this and I personally agree that we should do Feature Policy integration and that this would solve the nested iframe case. If others agree on this approach and use case, then I think this issue may be a duplicate of #10.

annevk commented 4 years ago

A problem here is that Feature Policy (and permissions too) are centered around origins, not sites. So while we could probably use it in some manner, there would be quite a few special cases still.

annevk commented 4 years ago

I suspect we would basically want to extend https://w3c.github.io/webappsec-feature-policy/#default-allowlists with a special default allowlist for requestStorageAccess(). One that means:

We'd also have to add the request-storage-access Permissions Policy identifier or something equivalent.

Reportedly this would be straightforward to add in Firefox.

cc @clelland @bakulf @johannhof

annevk commented 4 years ago

One thing that came up is that it might be nice if a first-party disables this, heuristics would also not be able to kick in for third-parties. (I'm not sure to what extent we define heuristics around storage access, but I guess we have to at least acknowledge they exist and maybe we can then also guide where they are allowed and disallowed.)

Brandr0id commented 4 years ago

I suspect we would basically want to extend https://w3c.github.io/webappsec-feature-policy/#default-allowlists with a special default allowlist for requestStorageAccess(). One that means: It's allowed by default in same-site documents. (And the permission is also automatically granted.) It's allowed in a cross-site document whose parent document is a top-level document.

Can we try to make use of an existing default policy such as allowed for all? This would let existing usage in the wild work as is. If I understand correctly this would also let top level sites specify a policy with a set of origins they want to allow (rather than the default *) to satisfy the threat model concern of having top level sites be in control of who can prompt their users for storage access. Currently this is what we've used in our implementation as a first pass.

We'd also have to add the request-storage-access Permissions Policy identifier or something equivalent.

How about "storage-access" ?

annevk commented 4 years ago

I don't see how an existing policy, especially 'self' would be web-compatible. I also don't think it should be called storage-access, since it's really about delegating the ability to prompt.

Brandr0id commented 4 years ago

I don't see how an existing policy, especially 'self' would be web-compatible.

Given the nature of the API to be useful with cross-origin content I don't think 'self' would make sense for sites to use. However it still seems reasonable that a default of '*' with the option for a site to override this with 'none' or a set of origins would satisfy the use-cases. Could you please elaborate further on your concerns with this?

I also don't think it should be called storage-access, since it's really about delegating the ability to prompt.

The API is about requesting access to storage and specifically what is granted by this is "storage access" which seems to align well with other permission names (this is also incorporating feedback I received from Chromium permission owners).

annevk commented 4 years ago

Well, Firefox and Safari both manage to ship a stricter default than '*'. I don't see why we would make that significantly looser.

Brandr0id commented 4 years ago

Well, Firefox and Safari both manage to ship a stricter default than '*'. I don't see why we would make that significantly looser.

Is this referencing the restriction to call the API in nested frames?

https://github.com/privacycg/storage-access/issues/10 calls out that this restriction limits use cases of developers. The main point that seems to be raised for the 'why' this restriction was initially added was that top-level documents should be able to control who prompts or doesn't prompt their users. Allowing the feature policy integration would provide that control via specifiable policy.

Trying to fit the default policy into the existing block nested frame framework seems like it may miss the spirit of the ask in https://github.com/privacycg/storage-access/issues/10 . This doesn't seem to be an uncommon pattern for other features and given that we do want the API useable in 3p by default I wouldn't want to advocate for a default like 'None'.

If there are further concerns to allowing nested frames (assuming we provide control mechanisms to developers to limit this) can you please help enumerate your threat model and concerns.

annevk commented 4 years ago

Letting developers opt out of the restriction seems fine, but removing the restriction by default entirely seems bad. Ideally over time we'd be able to make the default self, but same-site-self might be okay too, and for now it would have to be legacy-same-site-self-plus-one-level-of-cross-site-nesting or some such.

Brandr0id commented 4 years ago

Sorry to persist on the issue but are you able to articulate any specific concerns with nested 3p that are not present with first-child 3p?

A top-level document can control which 3p frames it includes and if they are concerned with them asking for storage access could sandbox the frame and omit the SAA sandbox token. However this would require a conscious change on the top-level sites part similar to applying a feature policy. The main difference is that without the nested frame restriction the top-level document can't selectively open up access for the first party child and not nested frames without a feature policy.

On top-level documents that have pre-existing embedded content they may have existing 3p frames that update to call the SAA and prompt the user without their knowledge today. If we opened up the nested frame restriction then nested 3ps could do the same. It seems hard to reason over why one 3p is potentially more dangerous than another 3p and concrete examples would be useful here.

Given the examples provided by developers and the reality that there is a lot of pre-existing embedded content on the web it would be nice to keep the barrier to activation of this API low in the absence of specific threats or concerns. The Dropbox example may be a case where Dropbox can easily be outreached to (and is engaged here) to update the top-level site. However it doesn't seem like an unreasonable pattern to ensure works by default.

annevk commented 4 years ago

Well, as I said, I'd like to shift to a more reasonable default of no prompting cross-origin/site. Opening things up more is in the wrong direction.

scottlow commented 4 years ago

Well, as I said, I'd like to shift to a more reasonable default of no prompting cross-origin/site

I may be misunderstanding the sentiment behind this comment, but per the MDN documentation for the Storage Access API, "The Storage Access API provides a way for embedded, cross-origin content to gain unrestricted access to storage that it would normally only have access to in a first-party context"

Wouldn't a default value of self (which would prevent prompting cross-origin/site) run counter to the defined purpose of the API and break all existing usage until first-parties updated their Feature Policies to re-enable cross-site usage?

I am supportive of the sentiment expressed by @johnwilander in #10 that first-parties should be in control of which third-parties can prompt for storage access. Beyond preserving existing usage of the API, a default-allowed policy such as the one @Brandr0id mentions above seems like it would achieve the use cases outlined in #10 while still providing first-parties with the ability to restrict which third-parties can request permission should they desire.

annevk commented 4 years ago

I don't see how requiring a permission to be delegated to be able to call such an API would go against its purpose. I do agree that it would not work currently, which is why it would require migration over time.

(Also, if you want everyone to have permission by default than Feature Policy (soon Permissions Policy) is not a good fit. It's fundamentally about delegation.)

scottlow commented 4 years ago

To me, it seems like eventually requiring delegation to use this API would unnecessarily a) introduce a breaking change and b) require an additional step that could hinder API adoption both without much benefit given that the API is designed to be called by embedded, cross-origin contexts. As @Brandr0id mentioned above, happy to talk through any specific concerns (both in the no-prompting-cross-origin/site case and in the no-nested-third-party-allowed-by-default case) that would motivate such changes.

(Also, if you want everyone to have permission by default than Feature Policy (soon Permissions Policy) is not a good fit. It's fundamentally about delegation.)

Are there plans to change Feature Policy to remove the default allowlist value of "*"? I'll admit I haven't been following the spec's evolution super closely, but from what I can gather, allowing the Storage Access API by default and giving first-parties a means to disable it via Feature Policy if they so choose falls squarely under the first use case from the introduction:

  1. The developer may want to selectively disable access to certain browser features and APIs to "lock down" their application, as a security or performance precaution, to prevent own and third-party content executing within their application from introducing unwanted or unexpected behaviors within their application.
annevk commented 4 years ago

The concern is letting third-parties show prompts without the first-party giving permission to do so. That we needed to reintroduce that because of state partitioning efforts does not make it a good long term solution.

And yeah, I expect the default allowlist '*' could be removed soonish.

johannhof commented 3 years ago

Closed by #78