From 12896c7feaf2e3155d8b109aa9e56150c2c94c62 Mon Sep 17 00:00:00 2001 From: Shuran Huang Date: Thu, 10 Aug 2023 15:20:54 +0000 Subject: [PATCH 1/5] Export the algo that gets user agent explicitly settings for unpartitioned cookie --- storage-access.bs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/storage-access.bs b/storage-access.bs index c91a733..7ba926f 100644 --- a/storage-access.bs +++ b/storage-access.bs @@ -126,6 +126,14 @@ A {{Document}} is in a first-party-site context if it is the [=active A {{Document}} is in a third party context if it is not in a [=first-party-site context=]. +Let whether the user agent explicitly allows unpartitioned cookie access be an algorithm that, given a [=tuple=] |tuple| consisting of two [=sites=], runs the following steps. This algorithm returns "`none`", "`allow`" or "`disallow`". + + Note: A user agent's settings might explicitly allow or disallow unpartitioned cookie access through per-site allow-lists, the user changing global browser settings, or similar custom overrides. + + 1. If the user agent does not have explicit settings for unpartitioned cookie access for |tuple|, return "`none`". + 1. If the user agent's settings explicitly allow unpartitioned cookie access for |tuple|, return "`allow`". + 1. If the user agent's settings explicitly disallow unpartitioned cookie access for |tuple|, return "`disallow`". +

Changes to user agent state related to storage access

Modify the definition of [=environment=] in the following manner: @@ -158,15 +166,7 @@ When invoked on {{Document}} |doc|, the ha 1. Let |topLevelSite| be the result of [=obtain a site|obtaining a site=] from the [=top-level origin=] of |doc|'s [=relevant settings object=]. 1. Let |embeddedSite| be the result of [=obtain a site|obtaining a site=] from |doc|'s [=Document/origin=]. 1. Run the following steps [=in parallel=]: - 1. Let |whether the user agent explicitly allows unpartitioned cookie access| be an algorithm that, given a [=tuple=] |tuple| consisting of two [=sites=], runs the following steps. This algorithm returns "`none`", "`allow`" or "`disallow`". - - Note: A user agent's settings might explicitly allow or disallow unpartitioned cookie access through per-site allow-lists, the user changing global browser settings, or similar custom overrides. - - 1. If the user agent does not have explicit settings for unpartitioned cookie access for |tuple|, return "`none`". - 1. If the user agent's settings explicitly allow unpartitioned cookie access for |tuple|, return "`allow`". - 1. If the user agent's settings explicitly disallow unpartitioned cookie access for |tuple|, return "`disallow`". - 1. Let |explicitSetting| be the result of determining |whether the user agent explicitly allows unpartitioned cookie access| with (|topLevelSite|, |embeddedSite|). - 1. Let |permissionState| be the result of [=getting the current permission state=] given "storage-access" and |global|. + 1. Let |explicitSetting| be the result of determining whether the user agent explicitly allows unpartitioned cookie access with (|topLevelSite|, |embeddedSite|). 1. [=Queue a global task=] on the [=networking task source=] given |global| to: 1. If |explicitSetting| is "`disallow`", [=/resolve=] |p| with false. 1. If |explicitSetting| is "`allow`", [=/resolve=] |p| with true. @@ -200,7 +200,7 @@ When invoked on {{Document}} |doc|, the re 1. Set |global|'s [=environment/has storage access=] to true. 1. [=/Resolve=] and return |p|. - NOTE: This check is [=same site=] on purpose, to allow embedded sites to use `requestStorageAccess()` to opt into storage access without involvement from the end user in scenarios where storage access is restricted for security and not privacy purposes. + NOTE: This check is [=same site=] on purpose, to allow embedded sites to use `requestStorageAccess()` to opt into storage access without involvement from the end user in scenarios where storage access is restricted for security and not privacy purposes. 1. If |doc|'s [=active sandboxing flag set=] has its [=sandbox storage access by user activation flag=] set, [=/reject=] |p| with a "{{NotAllowedError}}" {{DOMException}} and return |p|. 1. If |global|'s [=environment/has storage access=] is true, [=/resolve=] |p| with {{undefined}} and return. From e3deb7a55889a579e4d8c4f4e48146c4ea159cbb Mon Sep 17 00:00:00 2001 From: Shuran Huang Date: Thu, 10 Aug 2023 16:04:14 +0000 Subject: [PATCH 2/5] Update requestStorageAccess() to consider user explicit settings --- storage-access.bs | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/storage-access.bs b/storage-access.bs index 7ba926f..828aac0 100644 --- a/storage-access.bs +++ b/storage-access.bs @@ -192,18 +192,13 @@ When invoked on {{Document}} |doc|, the re 1. Let |global| be |doc|'s [=relevant global object=]. 1. Let |settings| be |doc|'s [=relevant settings object=]. 1. If |global| is not a [=secure context=], then [=/reject=] |p| with a "{{NotAllowedError}}" {{DOMException}} and return |p|. -1. If |doc|'s [=Document/browsing context=] is a [=top-level browsing context=], [=/resolve=] and return |p|. 1. If |doc| is not [=allowed to use=] "`storage-access`", [=/reject=] |p| with a "{{NotAllowedError}}" {{DOMException}} and return |p|. 1. If |doc|'s [=Document/origin=] is an [=opaque origin=], [=/reject=] |p| with a "{{NotAllowedError}}" {{DOMException}} and return |p|. -1. If |settings|'s [=top-level origin=] is an [=opaque origin=], [=/reject=] |p| with a "{{NotAllowedError}}" {{DOMException}} and return |p|. -1. If |settings|'s [=top-level origin=] is [=same site=] with |settings|'s [=environment settings object/origin=]: - 1. Set |global|'s [=environment/has storage access=] to true. - 1. [=/Resolve=] and return |p|. - - NOTE: This check is [=same site=] on purpose, to allow embedded sites to use `requestStorageAccess()` to opt into storage access without involvement from the end user in scenarios where storage access is restricted for security and not privacy purposes. - +1. If |settings|'s [=top-level origin=] is an [=opaque origin=], [=/reject=] |p| with a "{{NotAllowedError}}" {{DOMException}} and return |p|. 1. If |doc|'s [=active sandboxing flag set=] has its [=sandbox storage access by user activation flag=] set, [=/reject=] |p| with a "{{NotAllowedError}}" {{DOMException}} and return |p|. -1. If |global|'s [=environment/has storage access=] is true, [=/resolve=] |p| with {{undefined}} and return. +1. Let |browsingContext| be |doc|'s [=Document/browsing context=]. +1. Let |topLevelSite| be the result of [=obtain a site|obtaining a site=] from the [=top-level origin=] of |doc|'s [=relevant settings object=]. +1. Let |embeddedSite| be the result of [=obtain a site|obtaining a site=] from |doc|'s [=Document/origin=]. 1. Let |has transient activation| be whether |doc|'s {{Window}} object has [=transient activation=]. 1. Run the following steps [=in parallel=]: 1. Let |process permission state| be an algorithm that, given a [=permission state=] |state|, runs the following steps: @@ -214,6 +209,23 @@ When invoked on {{Document}} |doc|, the re 1. Else: 1. [=Consume user activation=] given |global|. 1. [=/Reject=] |p| with a "{{NotAllowedError}}" {{DOMException}}. + 1. Let |explicitSetting| be the result of determining whether the user agent explicitly allows unpartitioned cookie access with (|topLevelSite|, |embeddedSite|). + 1. If |explicitSetting| is "`disallow`": + 1. Run |process permission state| with [=permission/denied=]. + 1. Abort these steps. + 1. If |explicitSetting| is "`allow`": + 1. Run |process permission state| with [=permission/granted=]. + 1. Abort these steps. + 1. If |explicitSetting| is "`none`": + 1. If |browsingContext| is a [=top-level browsing context=]: + 1. Run |process permission state| with [=permission/granted=]. + 1. Abort these steps. + 1. If |embeddedSite| is [=same site=] with |topLevelSite|: + + NOTE: This check is [=same site=] on purpose, to allow embedded sites to use `requestStorageAccess()` to opt into storage access without involvement from the end user in scenarios where storage access is restricted for security and not privacy purposes. + + 1. Run |process permission state| with [=permission/granted=]. + 1. Abort these steps. 1. Let |previous permission state| be the result of [=getting the current permission state=] given "storage-access" and |global|. 1. If |previous permission state| is not [=permission/prompt=]: 1. Run |process permission state| with |previous permission state|. From baca0332bbf1bce897556335eef5ef8795fc8751 Mon Sep 17 00:00:00 2001 From: Shuran Huang <89418275+shuranhuang@users.noreply.github.com> Date: Mon, 18 Sep 2023 16:46:58 -0400 Subject: [PATCH 3/5] Apply suggestions from code review Co-authored-by: Johann Hofmann --- storage-access.bs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/storage-access.bs b/storage-access.bs index 828aac0..07fbf94 100644 --- a/storage-access.bs +++ b/storage-access.bs @@ -126,7 +126,7 @@ A {{Document}} is in a first-party-site context if it is the [=active A {{Document}} is in a third party context if it is not in a [=first-party-site context=]. -Let whether the user agent explicitly allows unpartitioned cookie access be an algorithm that, given a [=tuple=] |tuple| consisting of two [=sites=], runs the following steps. This algorithm returns "`none`", "`allow`" or "`disallow`". +To determine whether the user agent explicitly allows unpartitioned cookie access, given a [=tuple=] |tuple| consisting of two [=sites=], run the following steps. This algorithm returns "`none`", "`allow`" or "`disallow`". Note: A user agent's settings might explicitly allow or disallow unpartitioned cookie access through per-site allow-lists, the user changing global browser settings, or similar custom overrides. @@ -166,7 +166,7 @@ When invoked on {{Document}} |doc|, the ha 1. Let |topLevelSite| be the result of [=obtain a site|obtaining a site=] from the [=top-level origin=] of |doc|'s [=relevant settings object=]. 1. Let |embeddedSite| be the result of [=obtain a site|obtaining a site=] from |doc|'s [=Document/origin=]. 1. Run the following steps [=in parallel=]: - 1. Let |explicitSetting| be the result of determining whether the user agent explicitly allows unpartitioned cookie access with (|topLevelSite|, |embeddedSite|). + 1. Let |explicitSetting| be the result of [=determine whether the user agent explicitly allows unpartitioned cookie access|determining whether the user agent explicitly allows unpartitioned cookie access=] with (|topLevelSite|, |embeddedSite|). 1. [=Queue a global task=] on the [=networking task source=] given |global| to: 1. If |explicitSetting| is "`disallow`", [=/resolve=] |p| with false. 1. If |explicitSetting| is "`allow`", [=/resolve=] |p| with true. @@ -209,7 +209,7 @@ When invoked on {{Document}} |doc|, the re 1. Else: 1. [=Consume user activation=] given |global|. 1. [=/Reject=] |p| with a "{{NotAllowedError}}" {{DOMException}}. - 1. Let |explicitSetting| be the result of determining whether the user agent explicitly allows unpartitioned cookie access with (|topLevelSite|, |embeddedSite|). + 1. Let |explicitSetting| be the result of [=determine whether the user agent explicitly allows unpartitioned cookie access|determining whether the user agent explicitly allows unpartitioned cookie access=] with (|topLevelSite|, |embeddedSite|). 1. If |explicitSetting| is "`disallow`": 1. Run |process permission state| with [=permission/denied=]. 1. Abort these steps. From aaba84c1de4b2dd16f250b0c11fe7f2d60fb4e2a Mon Sep 17 00:00:00 2001 From: Shuran Huang Date: Mon, 18 Sep 2023 21:17:50 +0000 Subject: [PATCH 4/5] Use assertion. --- storage-access.bs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/storage-access.bs b/storage-access.bs index 07fbf94..1df2a71 100644 --- a/storage-access.bs +++ b/storage-access.bs @@ -132,7 +132,7 @@ To determine whether the user agent explicitly allows unpartitioned cookie 1. If the user agent does not have explicit settings for unpartitioned cookie access for |tuple|, return "`none`". 1. If the user agent's settings explicitly allow unpartitioned cookie access for |tuple|, return "`allow`". - 1. If the user agent's settings explicitly disallow unpartitioned cookie access for |tuple|, return "`disallow`". + 1. Assert: the user agent's settings explicitly disallow unpartitioned cookie access for |tuple| and return "`disallow`".

Changes to user agent state related to storage access

@@ -170,7 +170,7 @@ When invoked on {{Document}} |doc|, the ha 1. [=Queue a global task=] on the [=networking task source=] given |global| to: 1. If |explicitSetting| is "`disallow`", [=/resolve=] |p| with false. 1. If |explicitSetting| is "`allow`", [=/resolve=] |p| with true. - 1. If |explicitSetting| is "`none`": + 1. Assert: |explicitSetting| is "`none`": 1. If |browsingContext| is a [=top-level browsing context=], [=/resolve=] |p| with true. 1. If |browsingContext| is same authority with |browsingContext|'s [=top-level browsing context=]'s [=active document=], [=/resolve=] |p| with true. @@ -216,7 +216,7 @@ When invoked on {{Document}} |doc|, the re 1. If |explicitSetting| is "`allow`": 1. Run |process permission state| with [=permission/granted=]. 1. Abort these steps. - 1. If |explicitSetting| is "`none`": + 1. Assert: |explicitSetting| is "`none`": 1. If |browsingContext| is a [=top-level browsing context=]: 1. Run |process permission state| with [=permission/granted=]. 1. Abort these steps. From 8f7c1ea2d9cc2f4ab0e1dbd382e7deb2bb1ccd8c Mon Sep 17 00:00:00 2001 From: Shuran Huang Date: Tue, 19 Sep 2023 19:45:56 +0000 Subject: [PATCH 5/5] Apply suggestion around "Assert" --- storage-access.bs | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/storage-access.bs b/storage-access.bs index 1df2a71..63932f2 100644 --- a/storage-access.bs +++ b/storage-access.bs @@ -132,7 +132,8 @@ To determine whether the user agent explicitly allows unpartitioned cookie 1. If the user agent does not have explicit settings for unpartitioned cookie access for |tuple|, return "`none`". 1. If the user agent's settings explicitly allow unpartitioned cookie access for |tuple|, return "`allow`". - 1. Assert: the user agent's settings explicitly disallow unpartitioned cookie access for |tuple| and return "`disallow`". + 1. [=Assert=]: the user agent's settings explicitly disallow unpartitioned cookie access for |tuple|. + 1. Return "`disallow`".

Changes to user agent state related to storage access

@@ -167,18 +168,19 @@ When invoked on {{Document}} |doc|, the ha 1. Let |embeddedSite| be the result of [=obtain a site|obtaining a site=] from |doc|'s [=Document/origin=]. 1. Run the following steps [=in parallel=]: 1. Let |explicitSetting| be the result of [=determine whether the user agent explicitly allows unpartitioned cookie access|determining whether the user agent explicitly allows unpartitioned cookie access=] with (|topLevelSite|, |embeddedSite|). + 1. Let |permissionState| be the result of [=getting the current permission state=] given "storage-access" and |global|. 1. [=Queue a global task=] on the [=networking task source=] given |global| to: 1. If |explicitSetting| is "`disallow`", [=/resolve=] |p| with false. 1. If |explicitSetting| is "`allow`", [=/resolve=] |p| with true. - 1. Assert: |explicitSetting| is "`none`": - 1. If |browsingContext| is a [=top-level browsing context=], [=/resolve=] |p| with true. - 1. If |browsingContext| is same authority with |browsingContext|'s [=top-level browsing context=]'s [=active document=], [=/resolve=] |p| with true. + 1. [=Assert=]: |explicitSetting| is "`none`". + 1. If |browsingContext| is a [=top-level browsing context=], [=/resolve=] |p| with true. + 1. If |browsingContext| is same authority with |browsingContext|'s [=top-level browsing context=]'s [=active document=], [=/resolve=] |p| with true. - ISSUE: "same authority" here is a placeholder for a future concept that allows user agents to perform [=same site=] checks while adhering to additional security aspects such as the presence of a cross-site parent document, see [whatwg/storage#142](https://github.com/whatwg/storage/issues/142#issuecomment-1122147159). In practice, this might involve comparing the [=site for cookies=] or performing a [=same site=] check with the top-level document. - - 1. If |permissionState| is [=permission/granted=], [=/resolve=] |p| with |global|'s [=environment/has storage access=]. - - Note: The global storage access permission state takes precedence over the local [=environment/has storage access=] flag here, in order to immediately reflect a possible user choice to revoke the permission in their settings. + ISSUE: "same authority" here is a placeholder for a future concept that allows user agents to perform [=same site=] checks while adhering to additional security aspects such as the presence of a cross-site parent document, see [whatwg/storage#142](https://github.com/whatwg/storage/issues/142#issuecomment-1122147159). In practice, this might involve comparing the [=site for cookies=] or performing a [=same site=] check with the top-level document. + + 1. If |permissionState| is [=permission/granted=], [=/resolve=] |p| with |global|'s [=environment/has storage access=]. + + Note: The global storage access permission state takes precedence over the local [=environment/has storage access=] flag here, in order to immediately reflect a possible user choice to revoke the permission in their settings. 1. [=/Resolve=] |p| with false. 1. Return |p|. @@ -216,16 +218,16 @@ When invoked on {{Document}} |doc|, the re 1. If |explicitSetting| is "`allow`": 1. Run |process permission state| with [=permission/granted=]. 1. Abort these steps. - 1. Assert: |explicitSetting| is "`none`": - 1. If |browsingContext| is a [=top-level browsing context=]: - 1. Run |process permission state| with [=permission/granted=]. - 1. Abort these steps. - 1. If |embeddedSite| is [=same site=] with |topLevelSite|: + 1. [=Assert=]: |explicitSetting| is "`none`". + 1. If |browsingContext| is a [=top-level browsing context=]: + 1. Run |process permission state| with [=permission/granted=]. + 1. Abort these steps. + 1. If |embeddedSite| is [=same site=] with |topLevelSite|: - NOTE: This check is [=same site=] on purpose, to allow embedded sites to use `requestStorageAccess()` to opt into storage access without involvement from the end user in scenarios where storage access is restricted for security and not privacy purposes. + NOTE: This check is [=same site=] on purpose, to allow embedded sites to use `requestStorageAccess()` to opt into storage access without involvement from the end user in scenarios where storage access is restricted for security and not privacy purposes. - 1. Run |process permission state| with [=permission/granted=]. - 1. Abort these steps. + 1. Run |process permission state| with [=permission/granted=]. + 1. Abort these steps. 1. Let |previous permission state| be the result of [=getting the current permission state=] given "storage-access" and |global|. 1. If |previous permission state| is not [=permission/prompt=]: 1. Run |process permission state| with |previous permission state|.