Giter Site home page Giter Site logo

storage-access's People

Contributors

annevk avatar autokagami avatar bvandersloot-mozilla avatar bwalderman avatar cfredric avatar hober avatar johannhof avatar johnwilander avatar mreichhoff avatar shuranhuang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

storage-access's Issues

Integrate with the Permissions API or its model?

@Brandr0id wrote, in #29 (comment):

Now that we have a concept of a map storing the storage access flags does it make sense to just integrate with permissions that are keyed to the top-level and embedder origins rather than introduce a storage access map that's unique to this spec?

I could see the [=storage access map=] being a permission for Storage Access set with the [=partitioned storage key=] properties and the state "granted" or "denied" representing a success/failure of the API. The presence of the permissions "prompt" state and the concept of potentially prompting the user for access if no implicit grant is made may also tie nicely into this.

Make implicit deny and explicit deny indistinguishable

Implicit deny == the browser decides this third party is not allowed to request storage access and immediately rejects. This could be the result of policy or a user facing feature à la "Don't ask me again."
Explicit deny == the user gets prompted and chooses "Don't allow."

WebKit/Safari has seen misuse of the Storage Access API where the caller measures the time for the document.requestStorageAccess() promise to resolve/reject and changes behavior based on whether it was implicit or explicit. The goal seems to be to pressure users to allow storage access if they get prompted. In the specific case, the tap to play a video both starts playback and calls document.requestStorageAccess(). If the user is prompted and explicitly denies storage access, the video stops. The user can clearly see that it's possible to watch the video without storage access but is punished for not opting in. We've received multiple reports of this.

This is a tricky issue because of timing. One way is to always delay the resolve/reject. Another is to hang rather than reject and only execute the promise completion handler on resolve. A third would be to offer the user to some way lie, along the lines of "tell them I said yes but actually block access." I'm not sure the third option is something we could explain to users.

Active or passive storage access after explicit user opt-in

Mozilla's documentation on differences between Safari's and Firefox's implementation covers the difference explained below.

In this case, we assume that the user has explicitly opted in to storage access for third-party social.example under first-party blog.example.

Safari: iframes from social.example under blog.example always need to get user interaction and call document.requestStorageAccess() on that interaction to get cookie access. This means a mere page load of blog.example with an iframe from social.example does not grant the social.example iframe storage access.

Firefox: iframes from social.example under blog.example do not need to get user interaction or call document.requestStorageAccess() to get cookie access for 30 days after the explicit user opt-in. This means a mere page load of blog.example with an iframe from social.example grants the social.example iframe storage access.

Safari is unlikely to allow what we refer to as "passive tracking" and we think user interaction with the authenticated embed should be required for storage access. Hence the title of this issue "Active or passive storage access."

However, we're open to making this behavior optional. To reach consensus on how to spec this, it would be helpful to get Mozilla's use cases and motivations.

Consider moving API to Navigator

Proposal

In a similar way to how a Service Worker is registered to a limited scope, via Navigator:

navigator.serviceWorker.register(scriptUrl, { scope }); // scope defaults to same-origin requests of resources within same directory of scriptUrl

I'd like to put forward that storage access should be granted via Navigator too, scoped initially to the ownerDocument of the HTML Element that received a user action:

element.onclick = (e) => {
  navigator.requestStorageAccess(); // scoped to e.target.ownerDocument
}

Why?

Perhaps the biggest reason is flexibility for a future spec. I believe it could match the current behaviour by limiting the scope to the ownerDocument. However, if ever the spec were to change, or if different browsers wished to implement it differently... by having storage access granted to a double-keyed origin, to all iframes on the origin, or across page loads for instance, having it on the navigator allows for this widening of scope in perhaps a more comprehensible way.

Further arguments:

  • Storage access is given to HttpOnly cookies for network requests, which the document cannot access by definition.
  • Service Worker support: a service worker can be registered and shared across iframes, and is able to act as a proxy for requests that these iframes make. I cannot see how the current spec will be able to support the service worker making a request with credentials, as it does not have access to the document.
  • It's fairly trivial to read and write storage from an iframe that's on the same origin as an iframe whose document has been granted access. Or propagate the user action to trigger grants to all siblings, reducing the effectiveness of constraining it to a document.
  • Non-iframe access requests: Having to embed an iframe can be less desirable then embedding onto the main document for a variety of reasons. I can see a future where requests for storage access are not made from iframes, but from DOM/Shadow DOM elements on the first party that the third party owns.
  • I feel like several discussions within the other issues on this repo seem to support a widening of the scope.

For completeness:

navigator.hasStorageAccess(scope); // scope being document initially, or the flexibility to be something else, like third party origin

Thanks, would be really interested to hear any thoughts.

Means to observe availability of storage access

The storage access API provides for querying the storage access state (hasStorageAccess) and requesting changes (requestStorageAccess), but not observing changes. Authors could poll hasStorageAccess, but this is inefficient and unergonomic.

A frame might have multiple libraries or widgets which need to be updated when the user approves storage access. Currently, the solutions available to the author are:

  1. manually identify all libraries/widgets which need to be notified and all widgets which can trigger a request, and route notifications between them
  2. replace requestStorageAccess with a wrapper
  3. poll hasStorageAccess (wasting CPU cycles)

The first of these gets even harder if the flag set changes due to a change outside the document. For instance, a storage access request originating from a same-origin frame elsewhere on the page causes a change with no notification in the current CG draft (since these share a partitioned storage key and thus flag set).

The simplest solution would seem to be:

partial interface Document {
    readonly attribute Promise<void> storageAccessAvailable;
};

which resolves whenever hasStorageAccess would start resolving to true (i.e., has storage access flag for the flag set corresponding to the document is set and the was expressly denied storage flag is not set).

Sample usage:

let loggedInWidget = document.getElementById('logged-in');
loggedInWidget.textContent = 'Unknown';
document.storageAccessAvailable.then(() => {
    // Runs immediately if storage access is already available.
    // Otherwise runs when it is granted, if ever.
    loggedInWidget.textContent = localStorage.getItem('user') ?? 'Logged out';
});

Storage Types Covered

Mozilla's documentation on differences between Safari's and Firefox's implementation covers the difference explained below.

As mentioned in the original WHATWG issue on the Storage Access API, the naming implies that not only cookie access can be managed by this API but also other storage APIs such as LocalStorage and IndexedDB.

Safari: The Storage Access API only controls cookie access. All other storage APIs are either permanently partitioned (double-keyed) and ephemeral or blocked in third-party contexts.

Firefox: The Storage Access API controls all means of storage.

One of the main reasons for not covering more as of now in WebKit is that we have a shipping, privacy-preserving solution with our partitioning and switching it through the Storage Access API may cause breakage without progressing privacy. We need compelling use cases to consider effectively regressing these 7-year old privacy protections. Browser interoperability could be compelling, especially if we could get agreement across the board.

Add "Explicitly grant permission to sites globally" to considered alternatives

Just for completeness, it might be nice to lay out the reasoning here. To the extent that the concern is abuse or overuse, one could imagine explicit permission grants + in-browser reminders of when the permission is accessed working similarly to various mobile OS permissions in terms of striking a balance between usability and safety.

Storage Exists API

Apologies if there has already been discussion on this topic, I'm late to the discussion.

An API that allows the 1P to query if a 3P cookie exists would allow a 1P to only offer options to a user where the user has previously done something with the 3P site. The API would return a boolean value. For the social.example use case, the social button would only show up if there was a cookie at social.example.

The only abuse I can think of is a 1P site checking many 3Ps and using the results as a fingerprint.

Require reload after granting requestStorageAccess to get at unpartitioned storage

I don't see a clean path from partitioned storage to unpartitioned storage within a single navigation. I'd like to propose that we don't allow it, and instead force the frame to reload to get its unpartitioned storage post grant. This leads to a simpler and safer browser implementation, and a cleaner developer mental model.

While a reload may not be ideal from the third party's UX perspective, it should be a rare event since I believe all of the browsers that support requestStorageAccess preserve the access for some number of days. And there could be some ways to improve the UX (e.g., load the unpartitioned frame behind the first until it's ready).

@johnwilander @hober @annevk Thoughts?

SSO and autologin

My apologies if this has already been discussed. I read couple of long threads (e.g. whatwg/html#3338) and I just wanted to check the situation with SSO flows.

We basically have the similar case as mentioned by people from Auth0 (in that above thread).

Our organization owns multiple brands, and allow users to access these brands' sites with a single account, via SSO.

The flow is this:

  • User visits mybrand1.com and clicks "login"

  • User is redirected (or iframe) to mysso.com, fill up his username/password and logs in

  • User is redirected back to mybrand1.com and is logged in that site

  • User visits mybrand2.com

  • mybrand2.com automatically triggers a "hidden" call (e.g. hidden iframe) to mysso.com to check if user is logged in

  • If so, mysso.com completes the OAuth flow, and returns code/token back to mybrand2.com

  • User is automatically logged in mybrand2.com (and notified with a banner)

Would the Storage API allow such flow? It's still a bit confusing to me when user "interaction" is required.

Thank you for your time

Opt-in mechanism for shared storage access

We've discussed in both #3 and #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?

What should happen if the top-level origin is an opaque origin

A top-level document can sandbox itself. If it embeds tracker.example and that were to invoke requestStorageAccess(), what should happen?

I suspect we should disallow in this case as you cannot have meaningful UI.

We also generally do not allow storage for opaque origins so maybe storage would be disabled for the entire frame tree?

Storage access & first party set / CNAME feedback

In my opinion, on the storage access API - all modern user data privacy frameworks are requiring organizations identify categories of data sharing and most of these user data legal frameworks are requiring that orgs let users segment their access/sharing. The storage access API should tie directly into user data consent-sharing business categories and only let a 1st party request scope/storage into a 3rd party iframe when the consent string is also sent along with the storage access into 3rd party iframe.

Data revocation & deletion requests into the storage access API must have consent IDs corresponding back to users 1st party context and the 1st party data controller is responsible for submitting the 3rd party storage access deletion requests to data processors using the storage access API.

Users should be able to pick/choose which 3rd party companies are allowed to receive access from their 1st party visit and pass it through the Storage Access API and also be able to submit deletion/access requests through the 1st party in a way that makes it possible for the 1st party to submit the deletion request to the 3rd party via a user’s consent strings/IDs.

///

Furthermore, First Party Data Sets (Associated / Affiliated Domains) and any changes towards data sharing across first party data sets (Corporations that own multiple domains), even if the changes don't include "Dynamic first party data sets" - this creates massive user data vulnerabilities if the change is not also associated with "First Party Data Subdomain Authenticity Checks with CNAME to A Record Reverse Lookup Blocking" -- or something that FINALLY starts to address the massive problem of organizations stitching their domains together via subdomains & CNAME DNS mapping to get around technical browser restrictions between 1st/3rd party domains.

It's essential that as First Party Data Sets gets debated and as changes evolve here, that the CNAME subdomain hacks remain top of mind -- this is one of the WORST and MOST PERVASIVE ad technology hacks in existence and it gets worse every day, every week, every month. // Every month that goes by with more restrictions on 3rd party domains without corresponding restrictions on CNAME hacks, pushes ad tech further into a blurred 1st/2nd-party position using subdomain CNAME hacks that not only puts users in jeopardy, but also breaks most of the collaborative tracking infrastructure being discussed.

Also by ignoring CNAME hacks, this is creating an "internet business bubble" that will burst upon the global economy if organizations like PrivacyCG don't start to clearly say "This is bad, this is wrong, and it's going to stop in XX months via ZZY changes."

It's totally fine for this organization and people here to advocate strongly for First Party Data Sets so that their organizations can have SSO/Federated logins and keep the modern web -- but it's NOT okay for those same organizations and individuals to ignore the very real problems being created by CNAME subdomain hacks and how huge numbers of those very same companies that "need SSO/Federated logins" also have subsidiaries or products or benefit from data supply chains that use subdomain hacks to inject/exfiltrate user data in unsuspecting ways.

Thanks for everyone's time on these issues and the discussions.

Sincerely,
Zach

Define 'expression of permission' when user response is undefined

In 3.1.1. User Agent storage access policies an 'expression of permission' is defined to represent the result of prompting the user. The current state of true == explicit allow and false == explicit deny makes sense. I don't think we necessarily would want to set the 'was-expressly-denied-storage-access-flag' if they didn't expressly deny access.

However there exists the case where the prompt may be dismissed without providing a response. I believe it's best to treat these as a deny and reject the promise rather than leaving it unresolved but without the permanent effect so a subsequent prompt "may" be made if the UA allowed it. Can we call out this scenario in the spec where the expression of permission isn't explicitly true/false but the question has been resolved in an undefined manner?

Let first-parties list third-parties which can request storage access without further requirements

Prior to ITP 2.1, third-party websites had access to partitioned cookie storage when navigated to within an iframe.

With removal of partitioned storage and the introduction of ITP 2.3, it becomes necessary for third-party websites to request storage access from the user via the Storage Access API. However, if the user has not interacted with the third-party in a first-party context within the last 30 days, the API preemptively returns false before the user is prompted.

This creates a permission deadlock for websites that operate in an embed-only context and which depend on a session or authentication cookie for operation.

The workflow that appears to be necessary to circumvent this deadlock would require an artificial approach to: first flag the third-party as a first-party, then request storage access in third-party context.

Example scenario: website.example is a first-party website that displays a third-party website, information.exmaple, in an iframe. information.example needs to store a session or authentication cookie.

  1. user navigates to website.example which needs to render information.example in an iframe
  2. website.example redirects to information.example?returnUrl=website.example
  3. information.example displays some element and requests that the user interacts/gestures
  4. on user interaction, WebKit flags the domain as a 'domain having had first-party interaction within 30 days'
  5. information.example navigates to the returnUrl supplied by website.example
  6. website.example presents the iframe
  7. when the user interacts with the contents of the iframe, information.example requests storage access via the Storage Access API
  8. the Storage Access API request results in a user prompt with an ominous message asking to grant permission to information.example
  9. if allowed, information.example can store a session and/or authentication cookie and continue

This is a bad user experience by any measure and introduces a requirement for cooperation between the first-party and third-party that is unrealistic in many scenarios.

A solution to this would be to allow the first-party to whitelist the third-party domain when it defines the iframe, similar to <iframe>'s sandbox extension and the allow-storage-access-by-user-activation attribute.

For example: <iframe sandbox="allow-whitelisted-storage-access"></iframe>.

Reject with meaningful exceptions vs undefined.

It may be nice to reject failed calls to requestStorageAccess with an exception + message.

e.g. if no gesture => reject with a new DomException indicating "The method cannot be executed without a user gesture." and so on.

Any objections to this? I believe currently the promises are just rejected.

explicit revoke and automatic expiry

There should be a way for embedded contexts to explicitly revoke their storage access if they no longer need it, along with a way to pass an expiry time parameter when they call requestStorageAccess.
The expiry time would be limited to a overall browser enforced maximum.

Age Out Of Granted Storage Access

Mozilla's documentation on differences between Safari's and Firefox's implementation covers the difference explained below albeit with a slightly incorrect description of Safari's behavior.

Safari: Granted storage access is aged out when website data is deleted by the tracking prevention feature itself which triggers after 30 days of Safari use without user interaction. Successful use of the Storage Access API resets that counter.

Firefox: Granted storage access is aged out after 30 calendar days regardless of usage patterns.

I don't think the age out is a crucial part of the API so I'm fine leaving it as a browser choice in the spec.

Provide mechanism for nested iframes to request storage access

The original issue (whatwg/html#3338) and implementation in Safari and Firefox prevent all nested iframes from getting storage access (specifically step 7 "If the sub frame's parent frame is not the top frame, reject."). This breaks the use of iframes to isolate third party integrations for security when those third party integrations themselves include iframes that need access to cookies.

If simply removing the restriction isn't acceptable because of risk of abuse, I'd like to understand the concern better and see how we can safely allow users to consent to this use case. The current alternative to using iframes is including third party scripts in a first party context, which gives those scripts access to much more data, or asking users to disable tracking protections, both of which seem like undesirable outcomes for privacy.

An example of a broken use case for Dropbox is:

top frame: www.dropbox.com -- this is a top level link that a user visits to view a file
intermediate frame: gdd.dropbox.com -- this frame includes dynamic JS from the third party to view the file using the embedded third party editor
sub frame: docs.google.com -- this is the frame that actually shows the third party editor and wants to request storage access to personalize based on a user's existing account on the third party

Dropbox cannot include the sub frame directly without running dynamic Google JS because Google does not provide a stable API to do so.

Firefox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1611343
Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=205370

FeaturePolicy type header so top level site can ask for maximum privacy implementation

It would be useful for sites to ask browsers (via a response header), for a maximum privacy implementation by browsers for their embedded third-parties access to storage.
Some browsers may not default to prompting for all storage access requests, and sites may have to take further action if they are made aware of that.
This is so sites can rely on browsers to implement consent prompts for third-part storage access so top level sites do not have to, as they do under GDPR/ePrivacy. It could also be a way for sites to ensure they are respecting a user's opt-out, either via the site UI or a browser/device setting as implied by the CCPA AG regulations.
This could also help remove the need for cookie consent banners in Europe.
A corollary could be a request header that indicates the current privacy mode. A top-level site would
know that a browser instance will prompt the user for storage access if this request header is present.

Please tell me how to use Storage Access API correctly

I am testing on iOS13.4 Safari.
I found in the document below that 3rd-Party cookies are blocked.
https://webkit.org/blog/10218/full-third-party-cookie-blocking-and-more/
I tried option 2 storage access API, but storage access was denied.
My goal is to get permission with requestStorageAccess () and read / write third party cookies.

I created a simple demo site.
it's here
http://firstjun33930.com/test_iframe_parent/parent.php
When you press the UserAction button, console.log always passes "Storage Access Denied".

The contents of the code are as follows.

firstjun33930.com/test_iframe_parent/parent.php

<?php
setcookie("1st-party-cookie", "hoge", time() + 86400);
?>
<!DOCTYPE html>
<meta name="viewport" content="width=device-width,initial-scale=1">
<html>
  <head>
    <meta charset="UTF-8" />
    <title>iframe test</title>
  </head>
  <body>
    <div>
      parent.php
    </div>
    <ul>
      <li><a href="http://reoito.com/test_iframe_child/first_party_cookie.php">first party cookie set in reoito.com</a></li>
    </ul>
    <div>
      cookie:
    </div>
    <div>
        <pre><?=htmlspecialchars(print_r($_COOKIE), ENT_QUOTES)?></pre>
    </div>
    <div>
        <iframe src="http://reoito.com/test_iframe_child/child.php"
                sandbox="allow-storage-access-by-user-activation allow-scripts allow-same-origin"
                width="100%"
                height="400"
        >
        </iframe>
  </body>
</html>

reoito.com/test_iframe_child/child.php

<?php

setcookie("3rd-party-reoito.com", "hoge", time() + 86400);

?>
<!DOCTYPE html>
<meta name="viewport" content="width=device-width,initial-scale=1">
<html>
  <head>
    <meta charset="UTF-8" />
    <title>iframe test</title>
  </head>
  <body>
    <div>
      child.php
    </div>
    <div>
      cookie:
    </div>
    <div>
        <pre><?=htmlspecialchars(print_r($_COOKIE), ENT_QUOTES)?></pre>
    </div>
    <div>
        <button onclick="makeRequestWithUserGesture()">UserAction</button>
    </div>

    <script>
        function makeRequestWithUserGesture() {
            var promise = document.hasStorageAccess();
            promise.then(
                function (hasAccess) {
                    // Boolean hasAccess says whether the document has access or not.
                    console.log("hasStorageAccess:"+ hasAccess);

                    if (!hasAccess) {
                        var promise = document.requestStorageAccess();
                        promise.then(
                            function () {
                                // Storage access was granted.
                                console.log("Storage access was granted");
                            },
                            function () {
                                // Storage access was denied.
                                console.log("Storage access was denied");
                            }
                        );
                    }
                },
                function (reason) {
                    // Promise was rejected for some reason.
                    console.log("rejected for some reason:"+reason);
                }
            );
        }
    </script>
  </body>
</html>

Supporting display name and avoiding misuse of them

We've discussed display name as a version of the username suitable for user interfaces. This would allow the browser to show an account name that the user might be more familiar with. The user might have the formal username liza_johnson887 but the desired display name Lizza JSON. Can we support that in a safe way?

We have to make sure it cannot be misused to fake trusted browser signals. Imagine display names such as "Secure," "Private," "Logged Out," or "Anonymous," and the browser showing them in various contexts. Add localization to that and you have a real challenge. Add multi script such as Latin+Cyrillic and I'm remembering the struggle to defend URLs as a trust signal.

Consumption of User Gesture

In 3.1.1. User Agent storage access policies

The user gesture appears to be consumed if a prompt is rejected but not during any implicit grant without a prompt or if a prompt is allowed.

  1. If user expression of permission is false, let w be doc’s Window object and run these steps:
    1. If w has transient activation and user expression of permission is false, consume user activation with w.

This seems to be the only case the gesture would be consumed by this API, is there a specific reason to only consume it here or can we be consistent and always pass it through?

Per-Frame or Per-Page Storage Access

Mozilla's documentation on differences between Safari's and Firefox's implementation covers the difference explained below.

Safari: Storage access is granted only to the iframe that requested it, not to other iframes on the webpage and not to other subresources such as scripts and images.

Firefox: Storage access is granted to all matching subresources on the webpage such as iframes, scripts loads, and image loads.

We (WebKit) have received a few bugs where developers are asking for full storage access under the current webpage. Even so, our original intent for the API is to grant access to the specific embedded piece of content that needs it. Such a limited scope also guarantees that no other context such as other iframes or subresource loads suddenly have a change in their cookie access.

Mozillans, have you seen any issues arise from your full page scope? Did you have specific reasoning behind it?

Support for federated logins, or the ability to transfer IsLoggedIn

Back in the original explainer, we explored an idea on how to support federated logins (logging in to one website with an account from another website that is not part of the same organization, as opposed to single sign-on which is about the same organization). This is what was said there:

Some websites allow the user to use an existing account with a federated login provider to
bootstrap a new local user account and subsequently log in. The IsLoggedIn API needs to
support such logins.

First, the federated login provider needs to call the API on its side, possibly after the
user has clicked a “Log in with X” button:

navigator.initiateLoggedInFederated(destination: secure origin) –> Promise<void>

For the promise to resolve, the user needs to already have the IsLoggedIn status set for
the federated login provider, i.e. the user needs to be logged in to the provider first.

Then the destination website has to call the API on its side:

navigator.setLoggedInFederated(
    loginProvider: secure origin,
    username,
    credentialTokenType,
    optionalParams { }
) –> Promise<void>

The promise would only resolve if the loginProvider had recently called
setLoggedInFederated() for this destination website.

What this comes down to is the capability to set IsLoggedIn on DependingSite by taking the user through specific steps on IdentityProviderSite. This would allow IdentityProviderSite to "transfer the ability to set IsLoggedIn" to DependingSite without there having to be e.g. a login form on SiteA.

We should discuss this opportunity without being tied to the original proposal quoted above. The important part is to explore how to support such a transfer capability.

Sub-frames at same domain also acquire access

Regarding the scope of storage access, I'd like to request that sub-frames from the same domain also acquire storage access when their parent acquires storage access. This approach could be applied recursively down the frame tree.

When a user grants storage access to an iframe, they need not be concerned whether the contents of that iframe are a single page or made up of several pages from the same domain.

I've hit this issue as a developer making use of the Storage Access API. In our case, we are the third-party serving content from a Learning Management System inside of another (first-party) system. We don't have a choice but to make use of frames in order to support learning industry standards. Our main page holds a Javascript API, and then has two frames: one for the training module and one for course navigation.

In Safari 13.1, we're able to successfully acquire storage access for our main page, but then our sub-frames fail because they do not get access to our authentication cookie.

While our specific scenario might fall into the 'non-goals' category, I still believe this request makes sense. I can see this issue applying to others and don't see how it adds any further threat to tracking.

Option to specify extended lifetime

Brought up on the call but thought I'd make an issue to discuss further.

Since Safari announced limiting all storage data to 7 days there have been multiple posts from developers claiming this would affect their offline-only web app. I'm curious if we'd be interested in adding a parameter to the requestStorageAccess to specify a lifetime. The browser would choose to honor it or not and present it to the user if necessary. This could be called by a first-party if the offline-only app expected the user to need to have their data persist longer than the default expiration imposed by the browser.

Alternatively, it might be better to instead defer this to navigator.storage.persist() as defined in https://storage.spec.whatwg.org/. Since Safari doesn't implement that at the moment I thought I'd bring it up here in case they believe it's better to be handled by this spec instead.

Way to know who to prompt for storage access in the first place

(carrying this over from discussion started here and ended here)

Although this proposal aims to solve problems like "Subscribed video service," in practice it's unlikely that a service would want to prompt every single user for storage access when they click the play button just to find the fraction of users paying for ad-free access or hoping to include the video in their browsing history.

Similarly, part of the solution for "Social commenting widgets" not appearing be constantly logging you out (as discussed here) is to at least signal the user is one tap away from recustomizing the widget or writing a comment on a given site without distracting or making false promises to anybody else.

And for federated login / alternative billing services such as ours, we'd like for partners to be able to prominently remind our logged-in users to trigger storage access on their site without distracting visitors who do not have (already-logged-in) accounts.

For all of these use cases, it seems like we need some notion of isLoggedIn or trust tokens or explicit user permission to make storage access a viable, user-friendly solution. It sounded like this would end up being a separate proposal from Storage Access itself but at some level feels critical to cementing the plan for storage access.

requestStorageAccess API usage for embed only use-case.

From the Storage Access API documentation, the third-party website ( comments.com ) has to be accessed first as a first-party-site context by launching the third-party website in a 'standard browser address-bar' prior to landing into a page where the third-party website is embedded in the actual first party website (mysite.com).

However, this might not work for an embed only use-cases like Disqus or when there is sso / no-explicit authentication involved.

In such use-cases, how should the third-party establish itself as a first-party-site context ? If it is using popup window, we have observed that first-party-site context / cookies are lost when the popup is closed and manual switching between the popup and main window doesn't seem to be a good end-user interaction. Also the requestStorageAccess() doesn't work if you do not activate/focus the popup window manually.

Usage reference: https://webkit.org/blog/8124/introducing-storage-access-api/

document.requestStorageAccess() by top-level sites

Top-level sites could get the browser to issue a prompt on a storage access request, i.e. a call to
document.requestStorageAccess) by the top level site.
Some browsers may by default limit access to first-party cookies e.g. by an arbitrary limit to expiry duration, e.g. to mitigate third-party tracking via link decoration.
Even when this not a a default setting, browsers could enable it on a per site basis when a user has selected Do-Not-Sell, Do-Not-Track setting within the browser or via the site's UI.
Users could become accustomed to Storage Access prompts triggered by calls to document.requestStorageAccess() so it would make sense to the user if a similar prompt was triggered by a similar call by the top level site, when the result was to mitigate third-party tracking.
A similar amelioration of cookie restrictions could result from the browser detecting IsLoggedIn status.

Promptless storage access with constrained communication capabilities

@jkarlin brought up some ideas for the Storage Access API during the May 2020 virtual face-to-face meeting. From the meeting notes:

Josh Karlin: We want to avoid showing prompts to users when they'd have trouble making an informed decision. One possible idea: new types of iframes that might have constrained communication ability. e.g. think of an iframe that can't talk to the embedder. Maybe it's like a navigation: the user clicks, the constrained frame gets storage. Could work for a like button. Could work for a video that identifies that the user has paid and so they shouldn't see ads. Wouldn't work in cases where the embedding page needs to talk to the iframe. Still trying to investigate use cases, and we'll fall back to Storage Access if necessary.

Josh: We've been talking about having the 1st party embed it in a way that disclaims communication, which allows the 3rd party to have access. Could also imagine the 3rd party messaging it in response headers.

I thought about this and would like to share my view to see if we can get some progress here.

My interpretation of what Josh said is that there should be a way for a third-party iframe to request and be granted storage access without the purpose and means to communicate to the top frame, probably also not to sibling frames, possibly not even to child frames. I believe the intent is to stop migration of user identities between an iframe with storage access and the first party context of the top frame.

Is that accurate, Josh?

Say we were to offer an opt-in mode of the Storage Access API where the iframe gives up all its capabilities to talk to the rest of the page once it gets storage access. You could even envision this opt-in mode to be relaxed in some way, for instance be promptless which I think Google is shooting for given the "we want to avoid showing prompts to users" comment.

A straw man:
document.requestStorageAccess(options { scope : { singleIframeWithoutCommuncation, singleIframeWithCommunication, allSubresourcesWithCommunication } });

The vision for singleIframeWithoutCommuncation would be "Render the iframe with cookies as if it was a first party, isolated webpage with no further capabilities." This would be great for authenticated video embeds (henceforth videos.example) or authenticated document embeds that don't need to talk to anything else.

To achieve this opt-in isolation we'd:

  • Cut off postMessage.
  • Cut off scripting access across same-origin frames.
  • Return the empty string for document.referrer and any other signal of the iframe being embedded. (It might be impossible to fully fool the iframe to think that it's a top frame context.)
  • Cut off read access to the iframe's URL from the top frame.
  • Reload the iframe as part of granting it storage access so as to get rid of any temporary state stored in its JavaScript state or DOM.

The goal is to prevent any user identity leakage between the iframe and the top frame after storage access is granted.

Now imagine this:

  1. videos.example runs script in the first party context of a games.example webpage.
  2. The videos.example script stores a new random user ID in games.example's first party storage.
  3. The videos.example script opens an iframe with this URL: videos.example/?[videoClipID]&[new random user ID]
  4. The user taps to play the video, the iframe requests storage access with the optional singleIframeWithoutCommuncation, the browser skips the prompt, isolates the iframe, and reloads the iframe with cookies. Now videos.example has connected the new random user ID in games.example's storage with its own cookie user ID.

I don't see a way to stop that kind of user ID leakage. Do you?

Pinging @othermaciej @michaelkleber and @englehardt whom I think are interested in this too.

Align requestStorageAccess rejection w.r.t lack of user gesture

Currently, at least in Firefox, if document.requestStorageAccess is called without a user gesture and storage is not otherwise blocked the API appears to reject. This differs slightly from the wording in the spec draft and I wanted to make sure we pick/align current implementations and the spec to one behaviour here.

Currently the draft of the spec will let the promise resolve/reject immediately if either explicit allow/deny flags/state are set for the document. I also noticed the current draft text doesn't look to take into account the current state of storage access (e.g. let result be running determine if a site has storage access with key and doc and if result is true resolve p).

I can see both POV on this where if we have a prior signal that access is granted (either access is allowed or the allow/deny flags are set) then we can immediately resolve/reject. I can also see how if we don't have a user gesture, why would we potentially resolve or reject since the API shouldn't be usable without a gesture.

Thoughts on if it matters for the ordering here and depending on the result can we either update the spec language or open bugs on implementers for the behaviour change?

A side note, at least with the current impl logic of rejecting on gesture first we can get some test coverage in WPT to validate the API rejects while w3c/webdriver#1437 is active.

Scope of grant in terms of domains

I was reading https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Privacy/Storage_access_policy#Scope_of_storage_access yesterday and noticed that it does not use the registrable domain as the key.

In particular, if tracker.example is granted storage access on foo.example.com, and the user navigates to example.com that also embeds tracker.example, tracker.example does not have storage access. If the user then navigates to bar.foo.example.com which also embeds tracker.example, tracker.example does have storage access.

I suspect we are flexible with regards to this, but I thought I'd bring it up to see what people think.

iframes pass explanatory string

There should be a way for embedded contexts (e.g. iframes) to communicate an explanatory string to explain to the user (in the confirm prompt) what the purpose is for storage access, along with a declaration of who is asking, i..e. an independently verifiable indication of the data controllers identity.

The controller identity should be associated with the domain name somehow, perhaps as a JSON resource at a .well-known location similar to the DNT Tracking Status Resource, or tied to a DNS record using something like DBOUND.

The user-agent should refuse to deliver explanatory strings, and probably always deny storage access, to origins that are discovered to be lying.

Allow partitioned cookies

One way to allow partitioned storage for cookies would to allow embedded contexts to request the placement of double-keyed i .e. top level origin partitioned, cookies using a name prefix.

A third-party cookies with the name prefix (say) __k2_ (k2 means double keyed) would be partitioned and only visible in the context of the top level parent origin.

Other attempts to place 3rd party cookies without storage access would be blocked as per the Safari proposal.

This would be a very useful feature as it allows the storage of immediately available (to embedded contexts) user status such as site-specific consent, avoiding the need for a another round-trip or continuous complex cross domain postMessage handling. It could enable other privacy preserving techniques such as consent based targeted advertising.

requestStorageAccess for fetch?

I would be interested in a requestStorageAccess mechanism for fetch() calls made to third parties. We're building an embeddable javascript widget that would like to fetch() from a third party with {credentials: "include"}, but we don't use any iframes.

It looks like we can create an iframe, requestStorageAccess from within, then proxy to the iframe's instance of fetch() via postMessage, but it would be nice if we could shortcut that process with a requestStorageAccess mechanism for our embedder's instance of fetch().

For extra clarity:

  • embedder.com embeds service.com/widget.js
  • The code in widget.js makes a fetch() request to service.com/api/* with {credentials: "include"}

Third party cookies blockers prevent widget.com from receiving cookies, regardless of if the cookie has SameSite=None. We'd like to override the blocker with explicit user permission, so SameSite=None cookies are included with the request.

Please let me know if this isn't clear!

Triage issues

Many of the open issues can likely be closed, either because the conversation's concluded that no change is required or the conversation has timed out and the OP is no longer interested.

Out of the remaining issues, we should figure out which ones we still need to find consensus on, and which ones have already come to consensus and are just waiting on spec PRs.

Per-frame or per-frames-that-can-access-each-other

I'd like #3 to be clarified a bit. One thing I think is that if A embeds B1 that embeds B2, that B1 and B2 get their state flipped together as they can call each others functions. (In HTML terms the scope would be the window agent.)

Same if A embeds B1 and B2 (siblings).

Opt-out persistance

UseCase: As a user I want to opt-out of tracking by sniffy.com (sniffy.com has tracking pixels on many of the sites I visit) so that I can browser content on my favorite sites w/o sniffy.com being able to track me.

In this use case, persisting the users opt-out preferences across the domains he or she visits is a requirement (today that is done by setting a 3rd party cookie that sniffy can read, for example optout=true). W/o the ability to set a 3rd party cookie, sniffy needs a way to know what this users opt-out preferences are. We've explored the storage access api as an option and were curious to know whether the members of this group have consider it valid, or if there is an option more palatable?

opener browsing context check

If doc’s browsing context's opener browsing context is not its top-level browsing context, reject p.

I don't understand how this would work as most child browsing contexts wouldn't have an opener browsing context. Does this mean "is not a top-level browsing context" or something else?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.