From d0c8c6769169afdbe55d8e59ca97182a8cac6870 Mon Sep 17 00:00:00 2001 From: Theresa O'Connor Date: Fri, 10 Apr 2020 17:06:56 -0700 Subject: [PATCH 1/8] Initial, extremely rough, and incomplete attempt at a spec. --- storage-access.bs | 96 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 90 insertions(+), 6 deletions(-) diff --git a/storage-access.bs b/storage-access.bs index 44f3539..ab721b8 100644 --- a/storage-access.bs +++ b/storage-access.bs @@ -4,27 +4,111 @@ Shortname: storage-access Repository: privacycg/storage-access URL: https://privacycg.github.io/storage-access/ Editor: John Wilander, w3cid 89478, Apple Inc. https://apple.com/, wilander@apple.com -Abstract: TODO -Status Text: This specification is intended to be merged into the HTML Living Standard. It is neither a WHATWG Living Standard nor a W3C standard. +Abstract: The Storage Access API enables content in iframes to request access to cookies. +Status Text: This specification is intended to be merged into the HTML Living Standard. It is neither a WHATWG Living Standard nor is it on the standards track at W3C. Text Macro: LICENSE Creative Commons Attribution 4.0 International License Group: privacycg Status: CG-DRAFT Level: None +Markup Shorthands: markdown yes, css no +Complain About: accidental-2119 true + + + +

Introduction

This section is non-normative. -TODO +ISSUE: Write this section.

Infrastructure

-This specification depends on the Infra standard. [[!INFRA]] +This specification defines several additions to the HTML standard, and depends on the Infra standard. [[!INFRA]] [[!HTML]] + +

The Storage Access API

+ +Each {{Document}} has an associated has storage access flag, initially unset. + +
+partial interface Document {
+  Promise<boolean> hasStorageAccess();
+  Promise<void> requestStorageAccess();
+};
+
+ +When invoked, |document|.hasStorageAccess() must run these steps: + +1. Let |p| be [=a new promise=]. +1. If |document|'s [=has storage access flag=] is set, [=resolve=] |p| with true and abort these steps. +1. If the |document|'s [=active sandboxing flag set=] has its [=sandboxed origin browsing context flag=] set, [=resolve=] |p| with false and abort these steps. +1. If |document|'s browsing context is a [=top-level browsing context=], [=resolve=] |p| with true and abort these steps. +1. If |document|'s browsing context is [=same origin=] with its [=top-level browsing context=], [=resolve=] |p| with true and abort these steps. +1. Finish this algorithm. +1. [=If aborted=], return |p|. + +
+

Complete this algorithm. +

See its MDN page, WebKit implementation, and Gecko implementation. + +

+ +When invoked, |document|.requestStorageAccess() must run these steps: + +1. Let |p| be [=a new promise=]. +1. If |document|'s [=has storage access flag=] is set, [=resolve=] |p| and abort these steps. +1. If the |document|'s [=active sandboxing flag set=] has its [=sandboxed origin browsing context flag=] set, [=reject=] |p| and abort these steps. +1. If |document|'s [=has storage access flag=] is unset, [=reject=] |p| and abort these steps. +1. If |document|'s browsing context is a [=top-level browsing context=], [=resolve=] |p| and abort these steps. +1. If |document|'s browsing context is [=same origin=] with its [=top-level browsing context=], [=resolve=] |p| and abort these steps. +1. If the |document|'s {{Window}} object has [=transient activation=] and the |document|'s [=active sandboxing flag set=] has its [=sandbox storage access by user activation flag=] set, [=reject=] |p| and abort these steps. +1. If |document|'s browsing context's [=opener browsing context=] is not its [=top-level browsing context=], [=reject=] |p| and abort these steps. +1. If the algorithm is invoked when the |document|'s {{Window}} object does not have [=transient activation=], [=reject=] |p| and abort these steps. +1. Finish this algorithm. +1. [=If aborted=], return |p|. + +
+

Complete this algorithm. +

See its MDN page, WebKit implementation, and Gecko implementation. + +

+ +

Changes to {{Document/cookie}}

+ +ISSUE: Write this section. + +ISSUE(4): Should this API affect client-side storage other than cookies? + +

Sandboxing storage access

+ +A [=sandboxing flag set=] has a sandbox storage access by user activation flag. This flag prevents content from requesting storage access. + +To the [=parse a sandboxing directive=] algorithm, add the following under step 3: + + + +ISSUE(10): Provide mechanism for nested iframes to request storage access + +ISSUE(12): What about Feature Policy?

Acknowledgements

-Many thanks to -for their feedback on this proposal. +ISSUE: Write this section. From d62d30c3b812fd94ebc8e2a544cce50cb3705681 Mon Sep 17 00:00:00 2001 From: Theresa O'Connor Date: Mon, 13 Apr 2020 15:29:27 -0700 Subject: [PATCH 2/8] Start a section on navigation changes. --- storage-access.bs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/storage-access.bs b/storage-access.bs index ab721b8..58b36e7 100644 --- a/storage-access.bs +++ b/storage-access.bs @@ -16,6 +16,9 @@ Complain About: accidental-2119 true @@ -38,7 +50,10 @@ spec:html; type:dfn; text:current entry; url:https://html.spec.whatwg.org/multip This section is non-normative. -ISSUE: Write this section. +Browsers sometimes block access to client-side storage mechanisms in third-party contexts. This can break authenticated embeds such as commenting widgets, which often rely on cookies for authentication. + +The Storage Access API enables cross-origin iframes to request and be granted access to their client-side storage, so that authenticated embeds can work in such browsers. [[STORAGE-ACCESS-INTRO]] +

Infrastructure

@@ -81,11 +96,13 @@ When invoked, |document|.requestStorageAcc 1. If |document|'s browsing context is a [=top-level browsing context=], [=resolve=] |p| and abort these steps. 1. If |document|'s browsing context is [=same origin=] with its [=top-level browsing context=], [=resolve=] |p| and abort these steps. 1. If the |document|'s {{Window}} object has [=transient activation=] and the |document|'s [=active sandboxing flag set=] has its [=sandbox storage access by user activation flag=] set, [=reject=] |p| and abort these steps. -1. If |document|'s browsing context's [=opener browsing context=] is not its [=top-level browsing context=], [=reject=] |p| and abort these steps. +1. Remove this step when [privacycg/storage-access#10](https://github.com/privacycg/storage-access/issues/10) is resolved. If |document|'s browsing context's [=opener browsing context=] is not its [=top-level browsing context=], [=reject=] |p| and abort these steps. 1. If the algorithm is invoked when the |document|'s {{Window}} object does not have [=transient activation=], [=reject=] |p| and abort these steps. 1. Finish this algorithm. 1. [=If aborted=], return |p|. +ISSUE(10): Provide mechanism for nested iframes to request storage access +

Complete this algorithm.

See its MDN page, WebKit implementation, and Gecko implementation. @@ -96,12 +113,16 @@ When invoked, |document|.requestStorageAcc When the [=current entry=] of a [=browsing context=]'s [=session history=] changes, the [=has storage access flag=] of the {{Document}} of the old [=current entry=] is unset. -

Changes to {{Document/cookie}}

+ISSUE: Finish this section. -ISSUE: Write this section. +

Changes to various client-side storage mechanisms

ISSUE(4): Should this API affect client-side storage other than cookies? +

Cookies

+ +ISSUE: Write this section. +

Sandboxing storage access

A [=sandboxing flag set=] has a sandbox storage access by user activation flag. This flag prevents content from requesting storage access. @@ -112,10 +133,53 @@ To the [=parse a sandboxing directive=] algorithm, add the following under step
  • The [=sandbox storage access by user activation flag=], unless tokens contains the allow-storage-access-by-user-activation keyword. -ISSUE(10): Provide mechanism for nested iframes to request storage access - ISSUE(12): What about Feature Policy? -

    Acknowledgements

    +

    Privacy considerations

    ISSUE: Write this section. + +
    +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”. +
    An example prompt which could be shown to the user when a site calls `document.`{{Document/requestStorageAccess()}}.
    +
    + +

    Security considerations

    + +ISSUE: Write this section. + +

    Acknowledgements

    + +Many thanks to +Anne van Kesteren, +Ben Kelly, +Brad Girardeau, +Brad Hill, +Brandon Maslen, +Chris Mills, +Dave Longley, +Domenic Denicola, +Ehsan Akhgari, +Jack Frankland, +James Coleman, +James Hartig, +Jeffrey Yasskin, +Kushal Dave, +Luís Rudge, +Maciej Stachowiak, +Matias Woloski, +Mike O'Neill, +Mike West, +Pete Snyder, +Rob Stone, +Stefan Leyhane, +Steven Englehardt, +Theresa O'Connor, +Travis Leithead, +Yan Zhu, +Zach Edwards, +and everyone who commented on [whatwg/html#3338](https://github.com/whatwg/html/issues/3338), [privacycg/proposals#2](https://github.com/privacycg/proposals/issues/2), and [privacycg/storage-access/issues](https://github.com/privacycg/storage-access/issues) +for their feedback on this proposal. + +Thanks to the [WebKit Open Source Project](https://webkit.org/) for allowing us to use the [Storage Access API Prompt](#example-prompt) image, which was [originally published on webkit.org](https://webkit.org/blog/8311/intelligent-tracking-prevention-2-0/). From 8c9b71644cc769451a114fd0981912e773b321d6 Mon Sep 17 00:00:00 2001 From: Theresa O'Connor Date: Tue, 14 Apr 2020 11:36:38 -0700 Subject: [PATCH 5/8] Finish up hasStorageAccess() and requestStorageAccess(). --- storage-access.bs | 97 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 31 deletions(-) diff --git a/storage-access.bs b/storage-access.bs index 1182429..94fac66 100644 --- a/storage-access.bs +++ b/storage-access.bs @@ -50,9 +50,9 @@ spec:html; type:dfn; text:current entry; url:https://html.spec.whatwg.org/multip This section is non-normative. -Browsers sometimes block access to client-side storage mechanisms in third-party contexts. This can break authenticated embeds such as commenting widgets, which often rely on cookies for authentication. +User Agents sometimes block access to client-side storage mechanisms in third-party contexts. This can break authenticated embeds such as commenting widgets, which often rely on cookies for authentication. -The Storage Access API enables cross-origin iframes to request and be granted access to their client-side storage, so that authenticated embeds can work in such browsers. [[STORAGE-ACCESS-INTRO]] +The Storage Access API enables cross-origin <{iframe}>s to request and be granted access to their client-side storage, so that authenticated embeds can work in such User Agents. [[STORAGE-ACCESS-INTRO]] @@ -62,7 +62,7 @@ This specification defines several additions to the HTML standard, and depends o

    The Storage Access API

    -Each {{Document}} has an associated has storage access flag, initially unset. +

    Changes to {{Document}}

     partial interface Document {
    @@ -71,52 +71,87 @@ partial interface Document {
     };
     
    -When invoked, |document|.hasStorageAccess() must run these steps: +This specification defines two methods on {{Document}}: {{Document/hasStorageAccess()}} and {{Document/requestStorageAccess()}}. The {{Document/hasStorageAccess()}} method returns a {{Promise}} that resolves with a {{boolean}} indicating whether the document has access to its first-party storage. The {{Document/requestStorageAccess()}} method returns a {{Promise}} that resolves when the document has been granted access to its first-party storage, and rejects otherwise. + +Each {{Document}} has an associated has storage access flag, initially unset. + +Each {{Document}} has an associated was expressly denied storage access flag, initially unset. + +When invoked on {{Document}} |doc|, the hasStorageAccess() method must run these steps: + + + + 1. Let |p| be [=a new promise=]. -1. If |document|'s [=has storage access flag=] is set, [=resolve=] |p| with true and abort these steps. -1. If the |document|'s [=active sandboxing flag set=] has its [=sandboxed origin browsing context flag=] set, [=resolve=] |p| with false and abort these steps. -1. If |document|'s browsing context is a [=top-level browsing context=], [=resolve=] |p| with true and abort these steps. -1. If |document|'s browsing context is [=same origin=] with its [=top-level browsing context=], [=resolve=] |p| with true and abort these steps. -1. Finish this algorithm. +1. If |doc|'s [=was expressly denied storage access flag=] is set, [=resolve=] |p| with false and abort these steps. +1. If |doc|'s [=active sandboxing flag set=] has its [=sandboxed origin browsing context flag=] set, [=resolve=] |p| with false and abort these steps. +1. If |doc|'s browsing context is a [=top-level browsing context=], [=resolve=] |p| with true and abort these steps. +1. Let |topDoc| be the [=active document=] of |doc|'s browsing context's [=top-level browsing context=]. +1. If |doc| is [=same origin=] with |topDoc|, [=resolve=] |p| with true and abort these steps. +1. Resolve |p| with the result of running [=determine if a document has storage access=] with |doc| and |topDoc| and abort these steps. 1. [=If aborted=], return |p|. -
    -

    Complete this algorithm. -

    See its MDN page, WebKit implementation, and Gecko implementation. - -

    +When invoked on {{Document}} |doc|, the requestStorageAccess() method must run these steps: -When invoked, |document|.requestStorageAccess() must run these steps: + + + 1. Let |p| be [=a new promise=]. -1. If |document|'s [=has storage access flag=] is set, [=resolve=] |p| and abort these steps. -1. If the |document|'s [=active sandboxing flag set=] has its [=sandboxed origin browsing context flag=] set, [=reject=] |p| and abort these steps. -1. If |document|'s [=has storage access flag=] is unset, [=reject=] |p| and abort these steps. -1. If |document|'s browsing context is a [=top-level browsing context=], [=resolve=] |p| and abort these steps. -1. If |document|'s browsing context is [=same origin=] with its [=top-level browsing context=], [=resolve=] |p| and abort these steps. -1. If the |document|'s {{Window}} object has [=transient activation=] and the |document|'s [=active sandboxing flag set=] has its [=sandbox storage access by user activation flag=] set, [=reject=] |p| and abort these steps. -1. Remove this step when [privacycg/storage-access#10](https://github.com/privacycg/storage-access/issues/10) is resolved. If |document|'s browsing context's [=opener browsing context=] is not its [=top-level browsing context=], [=reject=] |p| and abort these steps. -1. If the algorithm is invoked when the |document|'s {{Window}} object does not have [=transient activation=], [=reject=] |p| and abort these steps. -1. Finish this algorithm. +1. If |doc|'s [=was expressly denied storage access flag=] is set, [=reject=] |p| and abort these steps. +1. If |doc|'s [=has storage access flag=] is set, [=resolve=] |p| and abort these steps. +1. If the |doc|'s [=active sandboxing flag set=] has its [=sandboxed origin browsing context flag=] set, [=reject=] |p| and abort these steps. +1. If |doc|'s browsing context is a [=top-level browsing context=], [=resolve=] |p| and abort these steps. +1. Let |topDoc| be the [=active document=] of |doc|'s browsing context's [=top-level browsing context=]. +1. If |doc| is [=same origin=] with |topDoc|, [=resolve=] |p| and abort these steps. +1. If |doc|'s [=active sandboxing flag set=] has its [=sandbox storage access by user activation flag=] set, [=reject=] |p| and abort these steps. +1. If |doc|'s browsing context's [=opener browsing context=] is not its [=top-level browsing context=], [=reject=] |p| and abort these steps. +1. If the algorithm is invoked when |doc|'s {{Window}} object does not have [=transient activation=], [=reject=] |p| and abort these steps. +1. [=Determine the storage access policy=] with |doc|, |topDoc|, and |p| and abort these steps. +1. Set |doc|'s [=has storage access flag=], [=resolve=] |p|, and abort these steps. 1. [=If aborted=], return |p|. -ISSUE(10): Provide mechanism for nested iframes to request storage access +ISSUE(10): Remove step 9 if we determine that nested <{iframe}>s should be able to request storage access. -
    -

    Complete this algorithm. -

    See its MDN page, WebKit implementation, and Gecko implementation. - -

    +

    User Agent storage access policies

    + +Different User Agents have different policies around whether or not third-party <{iframe}>'s may access data placed into client-side storage mechanisms when the <{iframe}>'s {{Document}}'s origin was loaded in a first-party context. User Agents check these policies when client-side storage is accessed (see [[#storage]]) as well as by {{Document/hasStorageAccess()}} and {{Document/requestStorageAccess()}}. + +When required to determine if a document has storage access with {{Document|Documents}} |doc| and |topDoc|, run these steps: + +1. Assert: |topDoc| is the [=active document=] of |doc|'s browsing context's [=top-level browsing context=]. +1. If |doc|'s [=has storage access flag=] is set, return true. +1. Let |has storage access| (a {{boolean}}) be the result of running a UA-defined set of steps to determine if |doc| has storage access when it is loaded in a third-party context on |topDoc|. +1. If |has storage access| is true, set |doc|'s [=has storage access flag=]. +1. Return |has storage access|. + +When required to determine the storage access policy for {{Document|Documents}} |doc| and |topDoc| with {{Promise}} |p|, run these steps: + +1. Assert: |topDoc| is the [=active document=] of |doc|'s browsing context's [=top-level browsing context=]. +1. Let |should implicitly grant| and |should implicitly deny| (both {{boolean|booleans}}) be the result of running a UA-defined set of steps to determine if |doc|'s request for storage access on |topDoc| should be granted or denied without prompting the user. +1. If |should implicitly grant| is true, [=resolve=] |p| and abort these steps. +1. If |should implicitly deny| is true, [=reject=] |p| and abort these steps. +1. Ask the user if they would like to grant |doc| access to its storage when it is loaded in a third-party context on |topDoc|, and wait for an answer. Let |user expression of permission| (a {{boolean}}) be the result. + + Note: if |user expression of permission| is false, the user **expressly chose** to deny |doc| access to its storage. +1. If |user expression of permission| is true, [=resolve=] |p|. +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|. + 1. Unset |doc|'s [=has storage access flag=]. + 1. Set |doc|'s [=was expressly denied storage access flag=]. + 1. [=Reject=] |p|. -When the [=current entry=] of a [=browsing context=]'s [=session history=] changes, the [=has storage access flag=] of the {{Document}} of the old [=current entry=] is unset. +Before changing the [=current entry=] of a [=session history=], unset the [=has storage access flag=] of the old [=current entry=]'s {{Document}}, if it has one. ISSUE: Finish this section.

    Changes to various client-side storage mechanisms

    +ISSUE: Write this section. For each kind of client-side storage affected, modify them to invoke [=determine if a document has storage access=] & modify their behavior based on the result. + ISSUE(4): Should this API affect client-side storage other than cookies?

    Cookies

    From c1225ad022d38a97b1523e823cb9c6eec263d877 Mon Sep 17 00:00:00 2001 From: Theresa O'Connor Date: Tue, 14 Apr 2020 11:37:18 -0700 Subject: [PATCH 6/8] Generate spec from commit 8c9b716. --- index.html | 2215 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2215 insertions(+) create mode 100644 index.html diff --git a/index.html b/index.html new file mode 100644 index 0000000..c25aabf --- /dev/null +++ b/index.html @@ -0,0 +1,2215 @@ + + + + The Storage Access API + + + + + + + + + + + + + + +
    +

    +

    The Storage Access API

    +

    Draft Community Group Report,

    +
    +
    +
    This version: +
    https://privacycg.github.io/storage-access/ +
    Issue Tracking: +
    GitHub +
    Inline In Spec +
    Editor: +
    (Apple Inc.) +
    +
    +
    + +
    +
    +
    +

    Abstract

    +

    The Storage Access API enables content in iframes to request access to website data (such as cookies).

    +
    +

    Status of this document

    +
    +

    This specification is intended to be merged into the HTML Living Standard. It is neither a WHATWG Living Standard nor is it on the standards track at W3C.

    +

    It was published by the Privacy Community Group. +Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. +Learn more about W3C Community and Business Groups.

    +
    +
    + +
    +
    +

    1. Introduction

    +

    This section is non-normative.

    +

    User Agents sometimes block access to client-side storage mechanisms in third-party contexts. This can break authenticated embeds such as commenting widgets, which often rely on cookies for authentication.

    +

    The Storage Access API enables cross-origin iframes to request and be granted access to their client-side storage, so that authenticated embeds can work in such User Agents. [STORAGE-ACCESS-INTRO]

    +
    +

    2. Infrastructure

    +

    This specification defines several additions to the HTML standard, and depends on the Infra standard. [INFRA] [HTML]

    +

    3. The Storage Access API

    +

    3.1. Changes to Document

    +
    partial interface Document {
    +  Promise<boolean> hasStorageAccess();
    +  Promise<void> requestStorageAccess();
    +};
    +
    +

    This specification defines two methods on Document: hasStorageAccess() and requestStorageAccess(). The hasStorageAccess() method returns a Promise that resolves with a boolean indicating whether the document has access to its first-party storage. The requestStorageAccess() method returns a Promise that resolves when the document has been granted access to its first-party storage, and rejects otherwise.

    +

    Each Document has an associated has storage access flag, initially unset.

    +

    Each Document has an associated was expressly denied storage access flag, initially unset.

    +

    When invoked on Document doc, the hasStorageAccess() method must run these steps:

    +
      +
    1. +

      Let p be a new promise.

      +
    2. +

      If doc’s was expressly denied storage access flag is set, resolve p with false and abort these steps.

      +
    3. +

      If doc’s active sandboxing flag set has its sandboxed origin browsing context flag set, resolve p with false and abort these steps.

      +
    4. +

      If doc’s browsing context is a top-level browsing context, resolve p with true and abort these steps.

      +
    5. +

      Let topDoc be the active document of doc’s browsing context’s top-level browsing context.

      +
    6. +

      If doc is same origin with topDoc, resolve p with true and abort these steps.

      +
    7. +

      Resolve p with the result of running determine if a document has storage access with doc and topDoc and abort these steps.

      +
    8. +

      If aborted, return p.

      +
    +

    When invoked on Document doc, the requestStorageAccess() method must run these steps:

    +
      +
    1. +

      Let p be a new promise.

      +
    2. +

      If doc’s was expressly denied storage access flag is set, reject p and abort these steps.

      +
    3. +

      If doc’s has storage access flag is set, resolve p and abort these steps.

      +
    4. +

      If the doc’s active sandboxing flag set has its sandboxed origin browsing context flag set, reject p and abort these steps.

      +
    5. +

      If doc’s browsing context is a top-level browsing context, resolve p and abort these steps.

      +
    6. +

      Let topDoc be the active document of doc’s browsing context’s top-level browsing context.

      +
    7. +

      If doc is same origin with topDoc, resolve p and abort these steps.

      +
    8. +

      If doc’s active sandboxing flag set has its sandbox storage access by user activation flag set, reject p and abort these steps.

      +
    9. +

      If doc’s browsing context’s opener browsing context is not its top-level browsing context, reject p and abort these steps.

      +
    10. +

      If the algorithm is invoked when doc’s Window object does not have transient activation, reject p and abort these steps.

      +
    11. +

      Determine the storage access policy with doc, topDoc, and p and abort these steps.

      +
    12. +

      Set doc’s has storage access flag, resolve p, and abort these steps.

      +
    13. +

      If aborted, return p.

      +
    +

    Remove step 9 if we determine that nested iframes should be able to request storage access. <https://github.com/privacycg/storage-access/issues/10>

    +

    3.1.1. User Agent storage access policies

    +

    Different User Agents have different policies around whether or not third-party iframe's may access data placed into client-side storage mechanisms when the iframe's Document's origin was loaded in a first-party context. User Agents check these policies when client-side storage is accessed (see § 3.3 Changes to various client-side storage mechanisms) as well as by hasStorageAccess() and requestStorageAccess().

    +

    When required to determine if a document has storage access with Documents doc and topDoc, run these steps:

    +
      +
    1. +

      Assert: topDoc is the active document of doc’s browsing context’s top-level browsing context.

      +
    2. +

      If doc’s has storage access flag is set, return true.

      +
    3. +

      Let has storage access (a boolean) be the result of running a UA-defined set of steps to determine if doc has storage access when it is loaded in a third-party context on topDoc.

      +
    4. +

      If has storage access is true, set doc’s has storage access flag.

      +
    5. +

      Return has storage access.

      +
    +

    When required to determine the storage access policy for Documents doc and topDoc with Promise p, run these steps:

    +
      +
    1. +

      Assert: topDoc is the active document of doc’s browsing context’s top-level browsing context.

      +
    2. +

      Let should implicitly grant and should implicitly deny (both booleans) be the result of running a UA-defined set of steps to determine if doc’s request for storage access on topDoc should be granted or denied without prompting the user.

      +
    3. +

      If should implicitly grant is true, resolve p and abort these steps.

      +
    4. +

      If should implicitly deny is true, reject p and abort these steps.

      +
    5. +

      Ask the user if they would like to grant doc access to its storage when it is loaded in a third-party context on topDoc, and wait for an answer. Let user expression of permission (a boolean) be the result.

      +

      Note: if user expression of permission is false, the user expressly chose to deny doc access to its storage.

      +
    6. +

      If user expression of permission is true, resolve p.

      +
    7. +

      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.

        +
      2. +

        Unset doc’s has storage access flag.

        +
      3. +

        Set doc’s was expressly denied storage access flag.

        +
      4. +

        Reject p.

        +
      +
    + +

    Before changing the current entry of a session history, unset the has storage access flag of the old current entry's Document, if it has one.

    +

    Finish this section.

    +

    3.3. Changes to various client-side storage mechanisms

    +

    Write this section. For each kind of client-side storage affected, modify them to invoke determine if a document has storage access & modify their behavior based on the result.

    +

    Should this API affect client-side storage other than cookies? <https://github.com/privacycg/storage-access/issues/4>

    +

    3.3.1. Cookies

    +

    Write this section.

    +

    3.4. Sandboxing storage access

    +

    A sandboxing flag set has a sandbox storage access by user activation flag. This flag prevents content from requesting storage access.

    +

    To the parse a sandboxing directive algorithm, add the following under step 3:

    + +

    What about Feature Policy? <https://github.com/privacycg/storage-access/issues/12>

    +

    4. Privacy considerations

    +

    Write this section.

    +
    + 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”. +
    An example prompt which could be shown to the user when a site calls document.requestStorageAccess().
    +
    +

    5. Security considerations

    +

    Write this section.

    +

    Acknowledgements

    +

    Many thanks to +Anne van Kesteren, +Ben Kelly, +Brad Girardeau, +Brad Hill, +Brandon Maslen, +Chris Mills, +Dave Longley, +Domenic Denicola, +Ehsan Akhgari, +Jack Frankland, +James Coleman, +James Hartig, +Jeffrey Yasskin, +Kushal Dave, +Luís Rudge, +Maciej Stachowiak, +Matias Woloski, +Mike O’Neill, +Mike West, +Pete Snyder, +Rob Stone, +Stefan Leyhane, +Steven Englehardt, +Theresa O’Connor, +Travis Leithead, +Yan Zhu, +Zach Edwards, +and everyone who commented on whatwg/html#3338, privacycg/proposals#2, and privacycg/storage-access/issues for their feedback on this proposal.

    +

    Thanks to the WebKit Open Source Project for allowing us to use the Storage Access API Prompt image, which was originally published on webkit.org.

    +
    +
    +

    Conformance

    +

    Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. + The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” + in the normative parts of this document + are to be interpreted as described in RFC 2119. + However, for readability, + these words do not appear in all uppercase letters in this specification.

    +

    All of the text of this specification is normative + except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

    +

    Examples in this specification are introduced with the words “for example” + or are set apart from the normative text with class="example", like this:

    +
    This is an example of an informative example.
    +

    Informative notes begin with the word “Note” + and are set apart from the normative text with class="note", like this:

    +

    Note, this is an informative note.

    +
    + +

    Index

    +

    Terms defined by this specification

    + + + + + + + + + + + + + + + + + + + + + + + + +

    Terms defined by reference

    +
      +
    • + [DOM] defines the following terms: +
        +
      • Document +
      • origin +
      +
    • + [HTML] defines the following terms: +
        +
      • Window +
      • active document +
      • active sandboxing flag set +
      • browsing context +
      • consume user activation +
      • current entry +
      • iframe +
      • opener browsing context +
      • parse a sandboxing directive +
      • same origin +
      • sandboxed origin browsing context flag +
      • sandboxing flag set +
      • session history +
      • top-level browsing context +
      • transient activation +
      +
    • + [INFRA] defines the following terms: +
        +
      • if aborted +
      +
    • + [WebIDL] defines the following terms: +
        +
      • Promise +
      • a new promise +
      • boolean +
      • reject +
      • resolve +
      +
    +

    References

    +

    Normative References

    +
    +
    [DOM] +
    Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/ +
    [HTML] +
    Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/ +
    [INFRA] +
    Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/ +
    [RFC2119] +
    S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119 +
    [WebIDL] +
    Boris Zbarsky. Web IDL. 15 December 2016. ED. URL: https://heycam.github.io/webidl/ +
    +

    Informative References

    +
    +
    [STORAGE-ACCESS-INTRO] +
    John Wilander. Introducing Storage Access API. February 2018. Blog post. URL: https://webkit.org/blog/8124/introducing-storage-access-api/ +
    +

    IDL Index

    +
    partial interface Document {
    +  Promise<boolean> hasStorageAccess();
    +  Promise<void> requestStorageAccess();
    +};
    +
    +
    +

    Issues Index

    +
    +
    Remove step 9 if we determine that nested iframes should be able to request storage access. <https://github.com/privacycg/storage-access/issues/10>
    +
    Finish this section.
    +
    Write this section. For each kind of client-side storage affected, modify them to invoke determine if a document has storage access & modify their behavior based on the result.
    +
    Should this API affect client-side storage other than cookies? <https://github.com/privacycg/storage-access/issues/4>
    +
    Write this section.
    + +
    Write this section.
    +
    Write this section.
    +
    + + + + + + + + \ No newline at end of file From 507b672c9818f0ab5f350ad60309d16b087e9bd9 Mon Sep 17 00:00:00 2001 From: Theresa O'Connor Date: Wed, 15 Apr 2020 14:24:57 -0700 Subject: [PATCH 7/8] Fixes and new issues based on @annevk's review. --- storage-access.bs | 67 ++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 27 deletions(-) diff --git a/storage-access.bs b/storage-access.bs index 94fac66..ca1522b 100644 --- a/storage-access.bs +++ b/storage-access.bs @@ -45,14 +45,24 @@ spec:html; type:dfn; text:current entry; url:https://html.spec.whatwg.org/multip } +ISSUE: don't use the terms "first party" and "third party" + +ISSUE: use the [=top-level origin=] concept from [[!HTML]]. + +ISSUE: [check for unique origin or opaque origin?](https://github.com/privacycg/storage-access/pull/24#discussion_r408779042) +

    Introduction

    This section is non-normative. -User Agents sometimes block access to client-side storage mechanisms in third-party contexts. This can break authenticated embeds such as commenting widgets, which often rely on cookies for authentication. +User Agents sometimes block access to client-side storage mechanisms in third party contexts. This can break authenticated embeds such as commenting widgets, which often rely on cookies for authentication. + +The Storage Access API enables cross origin <{iframe}>s to request and be granted access to their client-side storage, so that authenticated embeds can work in such User Agents. [[STORAGE-ACCESS-INTRO]] -The Storage Access API enables cross-origin <{iframe}>s to request and be granted access to their client-side storage, so that authenticated embeds can work in such User Agents. [[STORAGE-ACCESS-INTRO]] +ISSUE: [cross origin or cross site?](https://github.com/privacycg/storage-access/pull/24#discussion_r408771982) + +ISSUE: give other examples beyond authenticated embeds
    @@ -71,7 +81,7 @@ partial interface Document { }; -This specification defines two methods on {{Document}}: {{Document/hasStorageAccess()}} and {{Document/requestStorageAccess()}}. The {{Document/hasStorageAccess()}} method returns a {{Promise}} that resolves with a {{boolean}} indicating whether the document has access to its first-party storage. The {{Document/requestStorageAccess()}} method returns a {{Promise}} that resolves when the document has been granted access to its first-party storage, and rejects otherwise. +This specification defines two methods on {{Document}}: {{Document/hasStorageAccess()}} and {{Document/requestStorageAccess()}}. The {{Document/hasStorageAccess()}} method returns a {{Promise}} that resolves with a {{boolean}} indicating whether the document has access to its first party storage. The {{Document/requestStorageAccess()}} method returns a {{Promise}} that resolves when the document has been granted access to its first party storage, and rejects otherwise. Each {{Document}} has an associated has storage access flag, initially unset. @@ -84,13 +94,13 @@ When invoked on {{Document}} |doc|, the ha 1. Let |p| be [=a new promise=]. -1. If |doc|'s [=was expressly denied storage access flag=] is set, [=resolve=] |p| with false and abort these steps. -1. If |doc|'s [=active sandboxing flag set=] has its [=sandboxed origin browsing context flag=] set, [=resolve=] |p| with false and abort these steps. -1. If |doc|'s browsing context is a [=top-level browsing context=], [=resolve=] |p| with true and abort these steps. +1. If |doc|'s [=was expressly denied storage access flag=] is set, [=resolve=] |p| with false and return |p|. +1. If |doc|'s [=active sandboxing flag set=] has its [=sandboxed origin browsing context flag=] set, [=resolve=] |p| with false and return |p|. +1. If |doc|'s browsing context is a [=top-level browsing context=], [=resolve=] |p| with true and return |p|. 1. Let |topDoc| be the [=active document=] of |doc|'s browsing context's [=top-level browsing context=]. -1. If |doc| is [=same origin=] with |topDoc|, [=resolve=] |p| with true and abort these steps. -1. Resolve |p| with the result of running [=determine if a document has storage access=] with |doc| and |topDoc| and abort these steps. -1. [=If aborted=], return |p|. +1. If |doc| is [=same origin=] with |topDoc|, [=resolve=] |p| with true and return |p|. +1. Resolve |p| with the result of running [=determine if a document has storage access=] with |doc| and |topDoc|. +1. Return |p|. When invoked on {{Document}} |doc|, the requestStorageAccess() method must run these steps: @@ -99,40 +109,41 @@ When invoked on {{Document}} |doc|, the re 1. Let |p| be [=a new promise=]. -1. If |doc|'s [=was expressly denied storage access flag=] is set, [=reject=] |p| and abort these steps. -1. If |doc|'s [=has storage access flag=] is set, [=resolve=] |p| and abort these steps. -1. If the |doc|'s [=active sandboxing flag set=] has its [=sandboxed origin browsing context flag=] set, [=reject=] |p| and abort these steps. -1. If |doc|'s browsing context is a [=top-level browsing context=], [=resolve=] |p| and abort these steps. +1. If |doc|'s [=was expressly denied storage access flag=] is set, [=reject=] |p| and return |p|. +1. If |doc|'s [=has storage access flag=] is set, [=resolve=] |p| and return |p|. +1. If the |doc|'s [=active sandboxing flag set=] has its [=sandboxed origin browsing context flag=] set, [=reject=] |p| and return |p|. +1. If |doc|'s browsing context is a [=top-level browsing context=], [=resolve=] |p| and return |p|. 1. Let |topDoc| be the [=active document=] of |doc|'s browsing context's [=top-level browsing context=]. -1. If |doc| is [=same origin=] with |topDoc|, [=resolve=] |p| and abort these steps. -1. If |doc|'s [=active sandboxing flag set=] has its [=sandbox storage access by user activation flag=] set, [=reject=] |p| and abort these steps. -1. If |doc|'s browsing context's [=opener browsing context=] is not its [=top-level browsing context=], [=reject=] |p| and abort these steps. -1. If the algorithm is invoked when |doc|'s {{Window}} object does not have [=transient activation=], [=reject=] |p| and abort these steps. -1. [=Determine the storage access policy=] with |doc|, |topDoc|, and |p| and abort these steps. -1. Set |doc|'s [=has storage access flag=], [=resolve=] |p|, and abort these steps. -1. [=If aborted=], return |p|. +1. If |doc| is [=same origin=] with |topDoc|, [=resolve=] |p| and return |p|. +1. If |doc|'s [=active sandboxing flag set=] has its [=sandbox storage access by user activation flag=] set, [=reject=] |p| and return |p|. +1. If |doc|'s browsing context's [=opener browsing context=] is not its [=top-level browsing context=], [=reject=] |p| and return |p|. +1. If the algorithm is invoked when |doc|'s {{Window}} object does not have [=transient activation=], [=reject=] |p| and return |p|. +1. [=Determine the storage access policy=] with |doc|, |topDoc|, and |p|, and return |p|. +1. Set |doc|'s [=has storage access flag=], [=resolve=] |p|, and return |p|. ISSUE(10): Remove step 9 if we determine that nested <{iframe}>s should be able to request storage access. +ISSUE: [rewrite to not block the main thread.](https://github.com/privacycg/storage-access/pull/24#discussion_r408780546) +

    User Agent storage access policies

    -Different User Agents have different policies around whether or not third-party <{iframe}>'s may access data placed into client-side storage mechanisms when the <{iframe}>'s {{Document}}'s origin was loaded in a first-party context. User Agents check these policies when client-side storage is accessed (see [[#storage]]) as well as by {{Document/hasStorageAccess()}} and {{Document/requestStorageAccess()}}. +Different User Agents have different policies around whether or not third party <{iframe}>'s may access data placed into client-side storage mechanisms when the <{iframe}>'s {{Document}}'s origin was loaded in a first party context. User Agents check these policies when client-side storage is accessed (see [[#storage]]) as well as by {{Document/hasStorageAccess()}} and {{Document/requestStorageAccess()}}. When required to determine if a document has storage access with {{Document|Documents}} |doc| and |topDoc|, run these steps: 1. Assert: |topDoc| is the [=active document=] of |doc|'s browsing context's [=top-level browsing context=]. 1. If |doc|'s [=has storage access flag=] is set, return true. -1. Let |has storage access| (a {{boolean}}) be the result of running a UA-defined set of steps to determine if |doc| has storage access when it is loaded in a third-party context on |topDoc|. +1. Let |has storage access| (a {{boolean}}) be the result of running a UA-defined set of steps to determine if |doc| has storage access when it is loaded in a third party context on |topDoc|. 1. If |has storage access| is true, set |doc|'s [=has storage access flag=]. 1. Return |has storage access|. When required to determine the storage access policy for {{Document|Documents}} |doc| and |topDoc| with {{Promise}} |p|, run these steps: 1. Assert: |topDoc| is the [=active document=] of |doc|'s browsing context's [=top-level browsing context=]. -1. Let |should implicitly grant| and |should implicitly deny| (both {{boolean|booleans}}) be the result of running a UA-defined set of steps to determine if |doc|'s request for storage access on |topDoc| should be granted or denied without prompting the user. -1. If |should implicitly grant| is true, [=resolve=] |p| and abort these steps. -1. If |should implicitly deny| is true, [=reject=] |p| and abort these steps. -1. Ask the user if they would like to grant |doc| access to its storage when it is loaded in a third-party context on |topDoc|, and wait for an answer. Let |user expression of permission| (a {{boolean}}) be the result. +1. Let |implicitly granted| and |implicitly denied| (both {{boolean|booleans}}) be the result of running a UA-defined set of steps to determine if |doc|'s request for storage access on |topDoc| should be granted or denied without prompting the user. +1. If |implicitly granted| is true, [=resolve=] |p| and return. +1. If |implicitly denied| is true, [=reject=] |p| and return. +1. Ask the user if they would like to grant |doc| access to its storage when it is loaded in a third party context on |topDoc|, and wait for an answer. Let |user expression of permission| (a {{boolean}}) be the result. Note: if |user expression of permission| is false, the user **expressly chose** to deny |doc| access to its storage. 1. If |user expression of permission| is true, [=resolve=] |p|. @@ -142,11 +153,13 @@ When required to determine the storage access policy +ISSUE: [since this is UA-defined, does it make sense to follow-up separately with a user prompt?](https://github.com/privacycg/storage-access/pull/24#discussion_r408784492) + Before changing the [=current entry=] of a [=session history=], unset the [=has storage access flag=] of the old [=current entry=]'s {{Document}}, if it has one. -ISSUE: Finish this section. +ISSUE(3): What this section should look like ultimately hinges on this issue.

    Changes to various client-side storage mechanisms

    From c94752f0a351e10a9a7c797f95dd8a84541552c0 Mon Sep 17 00:00:00 2001 From: Theresa O'Connor Date: Wed, 15 Apr 2020 14:25:50 -0700 Subject: [PATCH 8/8] Regenerate based on 507b672. --- index.html | 92 +++++++++++++++++++++++++++++------------------------- 1 file changed, 50 insertions(+), 42 deletions(-) diff --git a/index.html b/index.html index c25aabf..99f83c4 100644 --- a/index.html +++ b/index.html @@ -1224,7 +1224,7 @@ - +