Skip to content

Commit

Permalink
Add Privacy and Security Considerations
Browse files Browse the repository at this point in the history
Hopefully this represents a good first version. Aiming to resolve privacycg#115.
  • Loading branch information
bvandersloot-mozilla committed Dec 14, 2022
1 parent 7908c22 commit 5e05619
Showing 1 changed file with 41 additions and 2 deletions.
43 changes: 41 additions & 2 deletions storage-access.bs
Original file line number Diff line number Diff line change
Expand Up @@ -310,17 +310,56 @@ The Storage Access API defines a [=policy-controlled feature=] identified by the

<h2 id="privacy">Privacy considerations</h2>

ISSUE: Write this section.
The Storage Access API enabled the removal of cross-site cookies. Specifically, it allows the authenticated embeds use case to continue to work. As such, the API provides a way for developers to re-gain access to cross-site cookies, albeit under further constraints.

A nested {{Document}} gains access to the same cookies it has as the [=active document=] of a [=top-level browsing context=] when it calls {{Document/requestStorageAccess()}} and is returned a resolving {{Promise}}. With these cookies it can authenticate itself to the server and load user-specific information.

While this functionality comes with a risk of abuse by third parties for tracking purposes, it is an explicit goal of the API and a key to its design to not undermine the gains of cross-site cookie deprecation.
Importantly, we do not degrade privacy properties when compared to pre-removal of cross-site cookies. This follows from a lack of platform-specific information used in the spec to prevent stateless tracking and the only state added being a permission scoped to the [=site|sites=] of the embedding and embedded [=Document=].

Our privacy considerations are more challenging where default cross-site cookies are already deprecated. The challenge is to decide when and how to permit the Storage Access API to be used to revert a cookie-less (or cookie-partitioned) nested {{Document}} to a pre-deprecation state, giving it access to its [=unpartitioned data=].

In an ideal case, an nested {{Document}} would only be able to gain access to its [=unpartitioned data=] if:

1. the user interacts with the nested {{Document}}
2. the nested {{Document}} is permitted by the embedder to use the API
3. the nested {{Document}} is a [=secure context=]
4. the user grants express, pairwise permission to the embeddee to use its cookies in the embedder
5. the user is not inundated by requests for the "<code>storage-access</code>" permission so their express permission is not undermined by fatigue

This specification requires the first three of implementers. This provides guarantees that the user is aware of the content of the nested {{Document}}, the embedder has not opted out of the nested {{Document}}'s authentication, and the cross-site cookies are not disclosed to network attackers, respectively.

The last two points are in tension. In an ideal world, we would show a prompt to the user in every call to {{Document/requestStorageAccess()}}. But, this would allow pages to prompt the user so frequently as to put the last point at the discretion of the page– a state we find unacceptable. User agents should prevent over-prompting of the user.

<figure id=example-prompt>
<img src=images/storage-access-prompt.png
alt="A modal dialog box which states 'Do you want to allow “video.example” to use cookies and website data while browsing “news.example”? This will allow “video.example” to track your activity.' and which has two buttons, “Don’t Allow” and “Allow”.">
<figcaption>An example prompt which could be shown to the user when a site calls `document.`{{Document/requestStorageAccess()}}.</figcaption>
</figure>

Thus, the last two points represent a key point of compromise. We permit [=implementation-defined=] behavior on when to grant or deny requests for [=unpartitioned data=] without requiring user choice so long as they meet all other requirements. This compromise weakens the privacy guarantees of this proposal, specifically point 4, to a degree under the control of the implementer and gives the implementer the power to render it impossible to get storage access with this API. However, this has proven necessary to enable condition 5 to be possible given our implementers' differing stances on the compromise between these two points.

Developer experience suffers where user agents differ greatly in their [=implementation-defined=] behavior, and therefore user agents should aim to minimize or standardize silent grants and denies.

<h3 id="site-scope">Permission scope</h3>

Another tension in the design of the API is what to use to key the "<code>storage-access</code>" permission: [=/origin|origins=] or [=site|sites=]. We chose [=site|sites=] because we believe them to be acceptable boundaries for privacy while enabling existing uses of [=same site=] and cross-origin nested {{Document|Documents}} on the same page with only one user prompt.

<h2 id="security">Security considerations</h2>

ISSUE: Write this section.
It is important that this spec not degrade security properties of the web platform, even when compared to post-removal of cross-site cookies. Third-party cookie removal has potential benefits for security, specifically in mitigating attacks that rely upon authenticated requests, e.g. CSRF. We do not wish the Storage Access API to be a foothold for such attacks to leverage.

To this end, we limit the impact of a "<code>storage-access</code>" permission grant to only give access to [=unpartitioned data=] to the nested {{Document}} that called {{Document/requestStorageAccess()}} and only until the nested {{Document}} navigates across an [=/origin=] boundary. This ensures that only [=/origin||origins=] with a page that call {{Document/requestStorageAccess()}} will be making credentialed requests, and moreover the embedee page can control which embedder it permits via the Content Security Policy "<code>frame-ancestors</code>" directive. This retains an [=/origin=]-scoped control for security purposes by the embedee.

<h3 id="reputation">Reputational attacks</h3>

This also is effective at preventing another attack: one on the embedee's reputation. We consider any cross-site authenticated request to have potential reputational harm as consumers become more privacy conscious. Therefore a first-party or sibling cross-site causing an embedded resource to be requested with the user's authentication cookies would constitute an attack on the reputation of that cross-site's owner. This is also a reason we require this API to be used in a [=secure context=]: so a network adversary cannot induce an embedee to use this API.

The embedder has control over which nested {{Document|Documents}} have the ability to become authenticated, or even display a permission request to the user via the Permission Policy and nested {{Document}} sandboxing.

<h3 id="notification">Notification abuse</h3>

Notification abuse was also considered while specifying the Storage Access API. Specifically, we require user interaction in the nested {{Document}} and consume that rejection on a denial to restrict the conditions a permission prompt will be shown to the user. This mitigates attacks such as re-requesting a permission immediately after the user denies it.

<h2 id="automation">Automation</h2>

Expand Down

0 comments on commit 5e05619

Please sign in to comment.