Bug 193277

Summary: Storage Access API doesn't appear to work
Product: WebKit Reporter: Martin <walking_fishy>
Component: WebCore Misc.Assignee: John Wilander <wilander>
Status: RESOLVED INVALID    
Severity: Blocker CC: beidson, bfulgham, cdumez, gabriel, othree, shahar, sihui_liu, stefan, webkit-bug-importer, wilander, xors.nn, youennf
Priority: P2 Keywords: InRadar
Version: Safari 12   
Hardware: Mac   
OS: macOS 10.13   
Attachments:
Description Flags
Example code none

Description Martin 2019-01-09 03:17:25 PST
Created attachment 358689 [details]
Example code

According to https://webkit.org/blog/8124/introducing-storage-access-api/ and https://developer.mozilla.org/en-US/docs/Web/API/Document/requestStorageAccess

there should be two functions:
* document.hasStorageAccess();
* document.requestStorageAccess();

despite hasStorageAccess() returning true, and the promise requestStorageAccess() resolving.
An iframe (siteB) is still unable to set and get cookies.

The iframe is sandboxed with the following attributes:
<iframe src = "http://siteB.com" sandbox="allow-storage-access-by-user-activation allow-scripts allow-same-origin"></iframe>

I have attached my example code as a zip.
Comment 1 Radar WebKit Bug Importer 2019-01-10 14:11:29 PST
<rdar://problem/47190019>
Comment 2 Gabe 2019-05-25 11:28:26 PDT
This still seems to be happening on Safari 12.1.1 on macOS 10.14.5.

The problem seems to goes away if the user first directly accesses "siteB" outside of an iframe.

Is this intended behavior? I was under the impression that the purpose of the Storage Access API was to allow third-party iframes to access cookies as long as the user interacts with the document inside the iframe and as long as the iframe requests permission. Requiring the user to have previously accessed the site inside the iframe hurts my use case.
Comment 3 othree 2019-12-09 07:38:21 PST
(In reply to Gabe from comment #2)
> This still seems to be happening on Safari 12.1.1 on macOS 10.14.5.
> 
> The problem seems to goes away if the user first directly accesses "siteB"
> outside of an iframe.
> 
> Is this intended behavior? I was under the impression that the purpose of
> the Storage Access API was to allow third-party iframes to access cookies as
> long as the user interacts with the document inside the iframe and as long
> as the iframe requests permission. Requiring the user to have previously
> accessed the site inside the iframe hurts my use case.

Hi Gabe.

What do you mean "The problem seems to goes away if the user first directly accesses "siteB" outside of an iframe."

Do you able to read and write the cookie in the iframe if you touched the domain outside?


I am using Safari 13 but I can't reproduce this behavior. I can only get read only access to the access to the cookie. It must write in a first party role (direct navigate or open a new window).
Comment 4 Sergey 2020-02-19 20:46:36 PST
The same for me 
(MacOS Catalina Version 10.15.3, Safari Version 13.0.5 (15608.5.11))

In the page in an Iframe running "hasStorageAccess" it resolves to false, then I run "requestStorageAccess" after it resolves "hasStorageAccess" resolves to true.
Then trying to set some cookie (both by javascript and by the backend call) the values of the cookies are not stored anywhere (nothing returns when accessing document.cookie)
Comment 5 Sergey 2020-02-19 20:48:51 PST
One addition to my previous comment, everything described there works fine on Firefox.
Comment 6 Shahar Galukman 2020-05-26 02:57:34 PDT
+1
Comment 7 John Wilander 2020-07-16 17:48:14 PDT
Hi all! I've been working on some documentation for the Storage Access API. See if this works for you (still a draft).

# How To Use the Storage Access API

We have received requests for a guide on how to successfully use the Storage Access API which enables embedded third-party content to get cookie access under Intelligent Tracking Prevention.

We refer to such embedded content as authenticated embeds since the purpose of getting cookie access typically is to authenticate the user. For the purposes of this guide we will use the domains social.example for the embedded content in need of cookie access and news.example as the website embedding social.example.

## Third-Party Iframes Call the API

The Storage Access API is called from inside cross-site, or third-party, iframes. You don’t have to call the API if your website is first party and first party websites cannot call the API on behalf of third-parties.

## First Meet and Greet the User as First Party

If you want to make use of the Storage Access API as a third-party, you first need to take these steps as a first party:

1. Take the user to your domain as first party. This is your website showing itself and giving the user a chance to recognize your brand and domain name. Recognition is important since the prompt for storage access features your embedded iframe’s domain. In our example, this is taking the user to a webpage with social.example in the URL bar, either though a navigation or a popup.

2. Have the user interact (tap, click, or use the keyboard) with your website as first party. This tells the browser that the user has actually seen and used the site. *Note*: Navigating to and from your website in a redirect without user interaction does not count. Formally, WebKit’s requirement is user interaction as first party the last 30 days of browser use. Being granted storage access through the Storage Access API counts as such user interaction. In our example, this is having the user tap/click on the webpage with social.example in the URL bar.

3. Set cookies when you are first-party. This establishes the website as "visited" for the purposes of the underlying cookie policy. Third parties without cookies cannot set cookies in Safari and never have since Safari 1.0 in 2003. This means you cannot use the Storage Access API as third-party until you have set at least one cookie as first party. In our example, this is setting cookies for social.example with social.example in the URL bar.

The above requirements are there to make sure the sometimes 50-100 embedded third-parties on a single webpage cannot all prompt the user for storage access, only the ones the user has visited and interacted with can.

## Now Use the Storage Access API as Third Party

Once you have had the user interact with your website as first party and have set cookies as first party, you are ready to make use of the Storage Access API.

1. Make your cross-site iframe call document.hasStorageAccess() as soon as it's rendered to check your status. *Note*: Don't call this function upon a user gesture since it's asynchronous and will consume the gesture, making a subsequent call to document.requestStorageAccess() fail because it's not called when processing a user gesture. In our example this is social.example's iframe.

2. If document.hasStorageAccess() returns false, your iframe doesn't have storage access. Now set an event handler on elements that represent UI which requires storage access and make the event handler call document.requestStorageAccess() on a tap or click. This is the API that requires a user gesture.  In our example this is social.example's iframe.

3. Render the page with your cross-site iframe. Tap or click on an element with an event handler in the iframe. In our example this is rendering a page from news.example with the social.example's iframe and clicking on an element in the social.example iframe's document.

4. If the user has not yet opted in to storage access for social.example under news.example there will now be a prompt. Choose "Don't Allow" in the prompt. *Tip*: Don't choose "Allow" yet because it'll be remembered and you'll have to delete browser history to reset it.

5. Test the behavior for the "Don't Allow" case. Do this until you’re happy with how your code handles it.

6. Now tap or click the iframe again and this time choose "Allow" in the prompt.

7. Test the behavior for the "Allow" case.