Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Intent to Implement: Storage Access API

512 views
Skip to first unread message

Ehsan Akhgari

unread,
Sep 7, 2018, 2:02:13 PM9/7/18
to dev-pl...@lists.mozilla.org
Hi everyone,

As we recently announced [0], we are working on a number of new
anti-tracking features which are intended to change the current approach in
Firefox with regards to how user’s data is shared with third-party trackers
as the user browses the web.

In the old world (the status quo for now), the data sharing is a
non-consensual and invisible part of browsing the web. We would like to
change this model by flipping the defaults, that is, make changes to
Firefox to avoid sharing user’s data with third-party trackers by default,
and also make the data sharing, where it happens, more visible and
controllable by the user. As part of these efforts we are experimenting
with a new cookie policy [1] that will block trackers from accessing
cookies and other storage while in a third-party context.

One of the new mechanisms that we would like to expose to web developers is
to ask for consent in order to gain access to the user’s data in a
third-party context. We are going to do this by adopting the Storage
Access API [2] implemented by Safari for a very similar purpose. At a
high-level, the Storage Access API allows content in third-party frames to
request access to storage on a specific first party that would otherwise be
blocked by our new policy. Safari uses this API as part of their
Intelligent Tracking Prevention [3] feature, and there are some differences
in the edge cases of how that feature works compared to our new cookie
policy. We discuss this in more detail below, but the main differences
include:

-

In our implementation, once Storage Access API grants storage access,
all existing third-party iframes on the same first party will receive that
storage access, whereas in WebKit’s implementation they each would require
calling requestStorageAccess() separately.
-

In our implementation, all future resource loads from a third party that
has been granted storage access will also be granted access on the same
first party. This includes access to third-party cookie headers for content
embedded into the main context of the page.
-

In our implementation, once the Storage Access API grants storage
access, all newly created third-party iframes of the same origin will have
storage access for a period of time (currently defined at 30 days) without
calling requestStorageAccess() again, whereas in WebKit’s implementation
they’d need to reaffirm their access by calling the API again.
-

In our implementation, when the promise returned from
requestStorageAccess() is resolved, the third-party context will have
access to its full first-party cookie jar. That includes things like
cookies, localStorage, IndexedDB, DOM Cache, and so on. In WebKit’s current
implementation, only access to cookies will be granted.
-

In our implementation, we phase out the granted storage access
permissions after a number of days passed, whereas in WebKit’s
implementation they phase out the permissions after a number of days of
browser usage passed.


We don’t necessarily believe that a model where the user is asked whether
they consent to sharing their data with third-party trackers is ideal,
because explaining the implications of the data sharing is very hard, and
there are many problems associated with asking for permission from the
user. But we are looking at this API as a programmatic hook into the point
in time when a third-party context would like to obtain full storage access
rights, which would allow the browser to perform various forms of
security/privacy checks at that time. Prompting the user is only one of the
options we’ve thought about so far. Note that the API limits granting
access only to callers coming at times when processing a user gesture.

Summary: Storage Access API is used to grant first-party storage access to
third-party embedded content under some browser controlled conditions. [2]

Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1469714

Link to standard: No standard exists yet, this is being discussed in
https://github.com/whatwg/html/issues/3338.

Platform coverage: All platforms.

Estimated or target release: Unclear as of yet (an intent to ship will be
sent later when a decision to ship has been made).

Preference behind which this will be implemented: dom.storage_access.enabled

Is this feature enabled by default in sandboxed iframes? No, the
allow-storage-access-by-user-activation sandbox flag enables it.

DevTools bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1462372. We
will be filing more specific bugs as we work through the scenarios where
devtools can assist web developers in order to use this functionality.

Do other browser engines implement this? Shipped in Safari 11.1, no public
signals from Chrome or Edge.

web-platform-tests: Our implementation unfortunately doesn’t come with
web-platform-tests, for two reasons. One is that there is currently no way
to mock user gestures in web platform tests [4], and the second reason is
that furthermore, our implementation also depends on being able to
manipulate the URL Classifier backend for testing purposes.

Is this feature restricted to secure contexts? No, because we would like to
be compatible with the WebKit implementation of this feature in terms of
exposure, which is already shipped to all contexts.

How stable is the spec: Safari is the only browser currently shipping the
feature, and we may be the 2nd browser if we get to that point soon.
Safari has changed some of the semantics around the API in ITP 2.0
recently. It’s possible for there to be further changes to the API before
we’re ready to ship. We’ll be working closely with other vendors who are
interested in collaborating on this space.

Security & Privacy Concerns:

- Does this specification deal with personally-identifiable information?
The API doesn’t expose new PII to the Web. It does permit the exposure
of PII to contexts where the browser would block such exposure by default.
The API is designed to allow the browser to intervene in the decision of
whether to grant storage access to a third party resource (e.g. through the
use heuristics, by prompting the user, etc.). We haven’t yet settled on
how to address this question in our implementation.

Note that, in the most permissive of possible implementations, this API
exposes no more information than is currently available in the default
cookie policy of Firefox. This does not provide a way for third parties to
access storage that would otherwise not be accessible today.
- Does this specification deal with high-value data?
Certainly, for example login tokens potentially stored in cookies; see
the bullet point above.
- Does this specification introduce new state for an origin that
persists across browsing sessions?
The specification does not mandate this, but our current implementation
remembers an affirmative grant of storage access to a given third party
under a first-party domain for 30 days. This state can be cleared when
clearing the site data through the existing UI the browser exposes. This
part of the design is subject to change.
- Does this specification expose persistent, cross-origin state to the
web?
No.
- Does this specification expose any other data to an origin that it
doesn’t currently have access to?
No.
- Does this specification enable new script execution/loading mechanisms?
No.
- Does this specification allow an origin access to a user’s location?
No.
- Does this specification allow an origin access to sensors on a user’s
device?
No.
- Does this specification allow an origin access to aspects of a user’s
local computing environment?
No.
- Does this specification allow an origin access to other devices?
No.
- Does this specification allow an origin some measure of control over a
user agent’s native UI?
No.
- Does this specification expose temporary identifiers to the web?
No.
- Does this specification distinguish between behavior in first-party
and third-party contexts?
Yes, see the algorithm in the whatwg/html issue.
- How should this specification work in the context of a user agent’s
"incognito" mode?
Our current implementation doesn’t grant storage access to documents
loaded in private windows.
- Does this specification persist data to a user’s local device?
As explained above, an affirmative result of the API call will be
persisted locally for 30 days.
- Does this specification have a "Security Considerations" and "Privacy
Considerations" section?
No.
- Does this specification allow downgrading default security
characteristics?
No.

Web designer / developer use-cases AKA Why a developer would use Feature X?
This feature will be useful for web developers working on websites that
require storage/cookie access when embedded in a third-party context. It
allows the developer to gain access to the first-party storage area (cookie
jar) of the website when it is embedded in third-party contexts.

Example: The following code samples shows a typical way in which this API
could be used in Firefox:

function storeData() {

window.localStorage[‘foo’] = 42;

}

try {
storeData();
} catch (e) {

document.requestLocalStorage().then(storeData, errorHandler);

}

[0]
https://blog.mozilla.org/futurereleases/2018/08/30/changing-our-approach-to-anti-tracking/

[1] https://bugzilla.mozilla.org/show_bug.cgi?id=1473978

[2] https://webkit.org/blog/8124/introducing-storage-access-api/

[3] https://webkit.org/blog/8311/intelligent-tracking-prevention-2-0/

[4] https://github.com/web-platform-tests/wpt/issues/7156


Cheers,
--
Ehsan

Tom Ritter

unread,
Sep 7, 2018, 2:32:33 PM9/7/18
to Ehsan Akhgari, Mozilla
On Fri, Sep 7, 2018 at 12:54 PM, Ehsan Akhgari <ehsan....@gmail.com>
wrote:

> In our implementation, once the Storage Access API grants storage
> access, all newly created third-party iframes of the same origin will
> have
> storage access for a period of time (currently defined at 30 days)
> without
> calling requestStorageAccess() again, whereas in WebKit’s implementation
> they’d need to reaffirm their access by calling the API again.
>
> ...
>
> In our implementation, we phase out the granted storage access
> permissions after a number of days passed, whereas in WebKit’s
> implementation they phase out the permissions after a number of days of
> browser usage passed.
>


These two were confusing to me. AIUI:

The first one is solely about having to call the requestStorageAccess() API
again. It sounds like you're saying we give a 30 day grace window while
safari expires things immediately; but that's not what you mean. It's
solely about whether the javascript code needs to call
requestStorageAccess() (even if it will be granted without a prompt) or if
it doesn't need to call it.

In Safari, you have to (even though it won't prompt), but in FF you won't
have to. In your pseudocode, I guess it works either way, but... what was
the reasoning for doing it this way instead of a pure Promise-based
approach?



In the second one:
Day 0: I do the thing, grant the access
Day 15: I sleep all day and don't use my browser
Day 30: Firefox expires permission
Day 31: Safari expires permission

It's solely about the difference between counting Day 15 towards 30 days.


-tom

James Graham

unread,
Sep 7, 2018, 2:49:49 PM9/7/18
to dev-pl...@lists.mozilla.org
> web-platform-tests: Our implementation unfortunately doesn’t come with
> web-platform-tests, for two reasons. One is that there is currently no way
> to mock user gestures in web platform tests [4], and the second reason is
> that furthermore, our implementation also depends on being able to
> manipulate the URL Classifier backend for testing purposes.

So this isn't true, however the present state of affairs may not yet be
useful to you.

It is currently possible to make basic user actions in wpt using the
testdriver API [1]. I am helping extend this to allow more general
guestures via WebDriver-like actions [2].

However it sounds like in this case you may need to add test-only APIs
for manipulating internal browser state. There are two possible
approaches here:

* Add a feature to WebDriver for manipulating this data. This can be
specified in the StorageManager spec and is appropriate if we want to
add something that can be used by authors as part of the automated
testing for their website.

* Add test-only DOM APIs in the StorageManager spec that we can enable
when running the browser in test mode. Each browser would be expected to
have some implementation-specific means to enable these APIs when under
test (e.g. a pref). WebUSB has an example of this approach.

> [4] https://github.com/web-platform-tests/wpt/issues/7156


[1] https://web-platform-tests.org/writing-tests/testdriver.html
[2] https://github.com/web-platform-tests/wpt/pull/12726
[3] https://wicg.github.io/webusb/test/

Ehsan Akhgari

unread,
Sep 7, 2018, 3:20:54 PM9/7/18
to Tom Lowenthal, dev-pl...@lists.mozilla.org
On Fri, Sep 7, 2018 at 2:32 PM Tom Ritter <t...@mozilla.com> wrote:

> On Fri, Sep 7, 2018 at 12:54 PM, Ehsan Akhgari <ehsan....@gmail.com>
> wrote:
>
>> In our implementation, once the Storage Access API grants storage
>> access, all newly created third-party iframes of the same origin will
>> have
>> storage access for a period of time (currently defined at 30 days)
>> without
>> calling requestStorageAccess() again, whereas in WebKit’s
>> implementation
>> they’d need to reaffirm their access by calling the API again.
>>
>> ...
>>
>> In our implementation, we phase out the granted storage access
>> permissions after a number of days passed, whereas in WebKit’s
>> implementation they phase out the permissions after a number of days of
>> browser usage passed.
>>
>
>
> These two were confusing to me. AIUI:
>

First thing to note, the expiry mechanism is completely independent of when
and how we choose to grant storage access, in case it helps clarify things.


> The first one is solely about having to call the requestStorageAccess()
> API again. It sounds like you're saying we give a 30 day grace window while
> safari expires things immediately; but that's not what you mean. It's
> solely about whether the javascript code needs to call
> requestStorageAccess() (even if it will be granted without a prompt) or if
> it doesn't need to call it.
>

That's right. It's also about the initial navigation of the document
having storage access (before the document has a chance to call any JS
APIs) which matters for HTTP layer cookies.


> In Safari, you have to (even though it won't prompt), but in FF you won't
> have to. In your pseudocode, I guess it works either way, but... what was
> the reasoning for doing it this way instead of a pure Promise-based
> approach?
>

What do you mean by "this way instead of a pure Promise-based approach"?
If you mean why we chose to grant this access when it has previously
granted before the page calls the API again, the short answer is for more
web compatibility.

One thing that I should explain here is that we also have a couple of
heuristics that try to detect when the user interacts with a third-party
widget in certain ways and grant this storage access automatically. These
are designed to catch scenarios such as logins using things like social
widgets, commenting widgets and the like. We'd like to treat the storage
access permissions the same, no matter whether they've been granted
automatically or programmatically through calling this API. The web
compatibility are mostly about the former scenario.


> In the second one:
> Day 0: I do the thing, grant the access
> Day 15: I sleep all day and don't use my browser
> Day 30: Firefox expires permission
> Day 31: Safari expires permission
>
> It's solely about the difference between counting Day 15 towards 30 days.
>

Right. I should also add that this isn't something that we particularly
like in the current implementation, and may consider improving on it in the
future. It's more a by-product of how our permission manager backend works.

Cheers,
--
Ehsan

Ehsan Akhgari

unread,
Sep 7, 2018, 4:28:27 PM9/7/18
to James Graham, dev-pl...@lists.mozilla.org
On Fri, Sep 7, 2018 at 2:49 PM James Graham <ja...@hoppipolla.co.uk> wrote:

> > web-platform-tests: Our implementation unfortunately doesn’t come with
> > web-platform-tests, for two reasons. One is that there is currently no
> way
> > to mock user gestures in web platform tests [4], and the second reason is
> > that furthermore, our implementation also depends on being able to
> > manipulate the URL Classifier backend for testing purposes.
>
> So this isn't true, however the present state of affairs may not yet be
> useful to you.
>
> It is currently possible to make basic user actions in wpt using the
> testdriver API [1]. I am helping extend this to allow more general
> guestures via WebDriver-like actions [2].
>

Very cool, I did not know this! It seems like test_driver.bless() is what
we need here for simulating a user activation gesture.


> However it sounds like in this case you may need to add test-only APIs
> for manipulating internal browser state. There are two possible
> approaches here:
>
> * Add a feature to WebDriver for manipulating this data. This can be
> specified in the StorageManager spec and is appropriate if we want to
> add something that can be used by authors as part of the automated
> testing for their website.
>
> * Add test-only DOM APIs in the StorageManager spec that we can enable
> when running the browser in test mode. Each browser would be expected to
> have some implementation-specific means to enable these APIs when under
> test (e.g. a pref). WebUSB has an example of this approach.
>

This is something that I should get some feedback on from at least WebKit
before deciding on a path forward, but from a Gecko perspective, we
basically need to call one function at the beginning and one function at
the end of each test, so looks like the first option would be sufficient.
Do you happen to have an example of that handy? I've never done something
like this before, and I do appreciate some pointers to get started.

I'm very happy to learn that it's possible to contribute wpt tests for this
feature!

Thanks,
--
Ehsan

Mike O'Neill

unread,
Sep 9, 2018, 5:05:57 AM9/9/18
to
This is great but I have a couple queries.
>
> In our implementation, once Storage Access API grants storage access,
> all existing third-party iframes on the same first party will receive that
> storage access, whereas in WebKit’s implementation they each would require
> calling requestStorageAccess() separately.
> -
>
Presumably this is restricted to iframes *of the same origin* on the same first party, i.e. if there are 2 iframes on different origins they would each still have to request storage access. Can you confirm this?


>
>
> We don’t necessarily believe that a model where the user is asked whether
> they consent to sharing their data with third-party trackers is ideal,
> because explaining the implications of the data sharing is very hard, and
> there are many problems associated with asking for permission from the
> user. But we are looking at this API as a programmatic hook into the point
> in time when a third-party context would like to obtain full storage access
> rights, which would allow the browser to perform various forms of
> security/privacy checks at that time. Prompting the user is only one of the
> options we’ve thought about so far. Note that the API limits granting
> access only to callers coming at times when processing a user gesture.
>
The legal requirement in Europe is that storage can only be accessed if the user has unambiguously given their "freely given, specific & informed" consent. How will a European website top-level context (first-party) ensure that embedded third-parties will not be granted storage access without the user first being prompted?

Thanks

Mike

Frederik Braun

unread,
Sep 10, 2018, 5:21:11 AM9/10/18
to Mike O'Neill, dev-pl...@lists.mozilla.org


On 09.09.2018 11:05, Mike O'Neill wrote:
>>
>> We don’t necessarily believe that a model where the user is asked whether
>> they consent to sharing their data with third-party trackers is ideal,
>> because explaining the implications of the data sharing is very hard, and
>> there are many problems associated with asking for permission from the
>> user. But we are looking at this API as a programmatic hook into the point
>> in time when a third-party context would like to obtain full storage access
>> rights, which would allow the browser to perform various forms of
>> security/privacy checks at that time. Prompting the user is only one of the
>> options we’ve thought about so far. Note that the API limits granting
>> access only to callers coming at times when processing a user gesture.
>>
> The legal requirement in Europe is that storage can only be accessed if the user has unambiguously given their "freely given, specific & informed" consent. How will a European website top-level context (first-party) ensure that embedded third-parties will not be granted storage access without the user first being prompted?

This is not really about sharing, is it?
AFAIU we plan to limit how third parties can look at their own storage
buckets - generally.
This API just allows them to poke a relatively well-defined hole (and
thus giving us an opportunity for intervention).


This API is mostly orthogonal to any data sharing between the first and
the third party - isn't it?

James Graham

unread,
Sep 10, 2018, 11:19:12 AM9/10/18
to Ehsan Akhgari, dev-pl...@lists.mozilla.org
On 07/09/2018 21:27, Ehsan Akhgari wrote:

> Very cool, I did not know this!  It seems like test_driver.bless() is
> what we need here for simulating a user activation gesture.
>
> However it sounds like in this case you may need to add test-only APIs
> for manipulating internal browser state. There are two possible
> approaches here:
>
> * Add a feature to WebDriver for manipulating this data. This can be
> specified in the StorageManager spec and is appropriate if we want to
> add something that can be used by authors as part of the automated
> testing for their website.
>
> * Add test-only DOM APIs in the StorageManager spec that we can enable
> when running the browser in test mode. Each browser would be
> expected to
> have some implementation-specific means to enable these APIs when under
> test (e.g. a pref). WebUSB has an example of this approach.
>
>
> This is something that I should get some feedback on from at least
> WebKit before deciding on a path forward, but from a Gecko perspective,
> we basically need to call one function at the beginning and one function
> at the end of each test, so looks like the first option would be
> sufficient.  Do you happen to have an example of that handy?  I've never
> done something like this before, and I do appreciate some pointers to
> get started.

You want an example of a spec adding a WebDriver-based test API? (I'm
not 100% sure I interpreted your message correctly). The permissions
spec has one [1].

[1] https://w3c.github.io/permissions/#automation

Ehsan Akhgari

unread,
Sep 11, 2018, 3:06:45 PM9/11/18
to ekimo...@gmail.com, dev-pl...@lists.mozilla.org
On Sun, Sep 9, 2018 at 5:10 AM Mike O'Neill <ekimo...@gmail.com> wrote:

> This is great but I have a couple queries.
> >
> > In our implementation, once Storage Access API grants storage access,
> > all existing third-party iframes on the same first party will receive
> that
> > storage access, whereas in WebKit’s implementation they each would
> require
> > calling requestStorageAccess() separately.
> > -
> >
> Presumably this is restricted to iframes *of the same origin* on the same
> first party, i.e. if there are 2 iframes on different origins they would
> each still have to request storage access. Can you confirm this?
>

Yes, of course.


> >
> >
> > We don’t necessarily believe that a model where the user is asked whether
> > they consent to sharing their data with third-party trackers is ideal,
> > because explaining the implications of the data sharing is very hard, and
> > there are many problems associated with asking for permission from the
> > user. But we are looking at this API as a programmatic hook into the
> point
> > in time when a third-party context would like to obtain full storage
> access
> > rights, which would allow the browser to perform various forms of
> > security/privacy checks at that time. Prompting the user is only one of
> the
> > options we’ve thought about so far. Note that the API limits granting
> > access only to callers coming at times when processing a user gesture.
> >
> The legal requirement in Europe is that storage can only be accessed if
> the user has unambiguously given their "freely given, specific & informed"
> consent. How will a European website top-level context (first-party) ensure
> that embedded third-parties will not be granted storage access without the
> user first being prompted?
>

In general in order to comply with regulations such as GDPR, websites need
to do a lot more than just look at the Storage Access API, so this is a
very partial answer to your question. The API provides the ability right
now for the embedder to control the ability of the embedded third-party to
request storage access using an iframe sandbox flag. In the future we may
consider adding further controls in this regard, for example, allowing the
top-level embedder to control whether the embedded content can call the API
using feature policy.

Please note that Firefox will grant storage access permissions
automatically under certain circumstances for web compatibility reasons, so
even when the iframe has never called this API it may still obtain storage
access. In order to prevent that from happening, the usual approaches
against embedded content gaining storage access (through sandboxing the
iframe to give it a unique origin) could be used.

Cheers,
--
Ehsan

Ehsan Akhgari

unread,
Sep 11, 2018, 3:08:58 PM9/11/18
to James Graham, dev-pl...@lists.mozilla.org
On Mon, Sep 10, 2018 at 11:19 AM James Graham <ja...@hoppipolla.co.uk>
wrote:
Thanks, this is exactly what I wanted to find!

--
Ehsan

Anne van Kesteren

unread,
Sep 12, 2018, 3:48:06 AM9/12/18
to Ehsan Akhgari, ekimo...@gmail.com, dev-platform
On Tue, Sep 11, 2018 at 9:06 PM Ehsan Akhgari <ehsan....@gmail.com> wrote:
> Please note that Firefox will grant storage access permissions
> automatically under certain circumstances for web compatibility reasons, so
> even when the iframe has never called this API it may still obtain storage
> access. In order to prevent that from happening, the usual approaches
> against embedded content gaining storage access (through sandboxing the
> iframe to give it a unique origin) could be used.

Unfortunately, that will still share cookies. Adding a feature policy
or some such for that might be worthwhile.

Ehsan Akhgari

unread,
Sep 12, 2018, 10:31:28 AM9/12/18
to Anne van Kesteren, Mike O'Neill, dev-pl...@lists.mozilla.org
Yes indeed. But that's beyond the scope of the current intent thread.

--
Ehsan
0 new messages