Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restrict to (top-level site, embedded origin) keying (fixes #39) #123

Merged
merged 2 commits into from
Oct 13, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 16 additions & 17 deletions storage-access.bs
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,11 @@ To <dfn type="abstract-op">obtain the storage access map</dfn> for a {{Document}

1. Return the [=agent cluster/storage access map=] of |doc|'s [=relevant agent=]'s [=agent cluster=].

A <dfn>partitioned storage key</dfn> is a [=tuple=] consisting of a <dfn for="partitioned storage key">top-level site</dfn> and an <dfn for="partitioned storage key">embedded site</dfn> (both [=sites=]).
A <dfn>partitioned storage key</dfn> is a [=tuple=] consisting of a <dfn for="partitioned storage key">top-level site</dfn> (a [=site=]) and an <dfn for="partitioned storage key">embedded origin</dfn> (an [=/origin=]).

<div class=example>

`(("https", "news.example"), ("https", "social.example"))` is a [=partitioned storage key=] whose [=top-level site=] is `("https", "news.example")` and whose [=embedded site=] is `("https", "social.example")`.
`(("https", "news.example"), ("https", "social.example", null, null))` is a [=partitioned storage key=] whose [=top-level site=] is `("https", "news.example")` and whose [=embedded origin=] is `("https", "social.example", null, null)`.

</div>

Expand All @@ -141,12 +141,12 @@ To <dfn type="abstract-op">generate a partitioned storage key</dfn> for a {{Docu
1. Let |top-level site| be the result of [=obtain a site|obtaining a site=] from |settings|' [=top-level origin=].
1. Return the [=partitioned storage key=] (|top-level site|, |site|).

A <dfn>storage access flag set</dfn> is a set of zero or more of the following flags, which are used to gate access to client-side storage for |embedded site| when loaded in a [=third party context=] on |top-level site|:
A <dfn>storage access flag set</dfn> is a set of zero or more of the following flags, which are used to gate access to client-side storage for |embedded origin| when loaded in a [=third party context=] on |top-level site|:

: The <dfn for="storage access flag set" id=has-storage-access-flag>has storage access flag</dfn>
:: When set, this flag indicates |embedded site| has access to its [=unpartitioned data=] when it's loaded in a [=third party context=] on |top-level site|.
:: When set, this flag indicates |embedded origin| has access to its [=unpartitioned data=] when it's loaded in a [=third party context=] on |top-level site|.
: The <dfn for="storage access flag set" id=was-expressly-denied-storage-access-flag>was expressly denied storage access flag</dfn>
:: When set, this flag indicates that the user expressly denied |embedded site| access to its [=unpartitioned data=] when it's loaded in a [=third party context=] on |top-level site|.
:: When set, this flag indicates that the user expressly denied |embedded origin| access to its [=unpartitioned data=] when it's loaded in a [=third party context=] on |top-level site|.

To <dfn type="abstract-op">obtain a storage access flag set</dfn> for a [=partitioned storage key=] |key| from a [=/storage access map=] |map|, run the following steps:

Expand Down Expand Up @@ -237,7 +237,7 @@ To <dfn type="abstract-op">determine if a site has storage access</dfn> with [=p
1. Let |map| be the result of [=obtain the storage access map|obtaining the storage access map=] for |doc|.
1. Let |flag set| be the result of [=obtain a storage access flag set|obtaining the storage access flag set=] with |key| from |map|.
1. If |flag set|'s [=has storage access flag=] is set, return true.
1. Let |has storage access| (a [=boolean=]) be the result of running an [=implementation-defined=] set of steps to determine if |key|'s [=partitioned storage key/embedded site=] has access to its [=unpartitioned data=] on |key|'s [=partitioned storage key/top-level site=].
1. Let |has storage access| (a [=boolean=]) be the result of running an [=implementation-defined=] set of steps to determine if |key|'s [=partitioned storage key/embedded origin=] has access to its [=unpartitioned data=] on |key|'s [=partitioned storage key/top-level site=].
1. If |has storage access| is true, set |flag set|'s [=has storage access flag=].
1. [=Save the storage access flag set=] for |key| in |map|.
1. Return |has storage access|.
Expand All @@ -246,13 +246,13 @@ To <dfn type="abstract-op">determine the storage access policy</dfn> for [=parti

1. Let |map| be the result of [=obtain the storage access map|obtaining the storage access map=] for |doc|.
1. Let |flag set| be the result of [=obtain a storage access flag set|obtaining the storage access flag set=] with |key| from |map|.
1. Let |implicitly granted| and |implicitly denied| (each a [=boolean=]) be the result of running an [=implementation-defined=] set of steps to determine if |key|'s [=partitioned storage key/embedded site=]'s request for storage access on |key|'s [=partitioned storage key/top-level site=] should be granted or denied without prompting the user.
1. Let |implicitly granted| and |implicitly denied| (each a [=boolean=]) be the result of running an [=implementation-defined=] set of steps to determine if |key|'s [=partitioned storage key/embedded origin=]'s request for storage access on |key|'s [=partitioned storage key/top-level site=] should be granted or denied without prompting the user.

Note: These [=implementation-defined=] set of steps might result in |flag set|'s [=has storage access flag=] and [=was expressly denied storage access flag=] changing, since the User Agent could have relevant out-of-band information (e.g. a user preference that changed) that this specification is unaware of.
1. Let |global| be |doc|'s [=relevant global object=].
1. If |implicitly granted| is true, [=queue a global task=] on the [=permission task source=] given |global| to [=/resolve=] |p|, and return.
1. If |implicitly denied| is true, [=queue a global task=] on the [=permission task source=] given |global| to [=/reject=] |p| with a "{{NotAllowedError}}" {{DOMException}}, and return |p|.
1. Ask the user if they would like to grant |key|'s [=partitioned storage key/embedded site=] access to its [=unpartitioned data=] when it's loaded in a [=third party context=] on |key|'s [=partitioned storage key/top-level site=], and wait for an answer. Let |expressly granted| and |expressly denied| (both [=booleans=]) be the result.
1. Ask the user if they would like to grant |key|'s [=partitioned storage key/embedded origin=] access to its [=unpartitioned data=] when it's loaded in a [=third party context=] on |key|'s [=partitioned storage key/top-level site=], and wait for an answer. Let |expressly granted| and |expressly denied| (both [=booleans=]) be the result.

Note: While |expressly granted| and |expressly denied| cannot both be true, they could both be false in User Agents which allow users to dismiss the prompt without choosing to allow or deny the request. (Such a dismissal is interpreted in this algorithm as a denial.)
1. If |expressly granted| is true, run these steps:
Expand Down Expand Up @@ -345,27 +345,26 @@ The [=remote end steps=] are:

1. Let |blocked| be the result of [=getting a property=] from |parameters| named `blocked`.
1. If |blocked| is not a [=boolean=] return a [=WebDriver error=] with [=WebDriver error code=] [=invalid argument=].
1. Let |origin| be the result of [=getting a property=] from |parameters| named `origin`.
1. If |origin| is not a single U+002A ASTERISK character (*), then:
1. Let |parsedURL| be the the result of running the [=URL parser=] on |origin|.
1. Let |embedded origin| be the result of [=getting a property=] from |parameters| named `origin`.
1. If |embedded origin| is not a single U+002A ASTERISK character (*), then:
1. Let |parsedURL| be the the result of running the [=URL parser=] on |embedded origin|.
1. If |parsedURL| is failure, then return a [=WebDriver error=] with [=WebDriver error code=] [=invalid argument=].
1. Set |origin| to |parsedURL|'s [=url/origin=].
1. Set |embedded origin| to |parsedURL|'s [=url/origin=].
1. If the [=current browsing context=] is not a [=top-level browsing context=] return a [=WebDriver error=] with [=WebDriver error code=] [=unsupported operation=].
1. Let |doc| be the [=current browsing context=]'s [=active document=].
1. Let |settings| be |doc|'s [=relevant settings object=].
1. Let |top-level site| be the result of [=obtain a site|obtaining a site=] from |settings|'s [=environment settings object/origin=].
1. If |origin| is a single U+002A ASTERISK character (*), then:
1. If |embedded origin| is a single U+002A ASTERISK character (*), then:
1. If |blocked| is `true`, then:
1. Run an [=implementation-defined=] set of steps to ensure that no site has access to its [=unpartitioned data=] when loaded in a [=third party context=] on |top-level site|.
1. Otherwise, if |blocked| is `false`, then:
1. Run an [=implementation-defined=] set of steps to ensure that any site has access to its [=unpartitioned data=] when loaded in a [=third party context=] on |top-level site|.
1. Otherwise:
1. Let |embedded site| be the result of [=obtain a site|obtaining a site=] from |origin|.
1. If |embedded site| is [=same site=] with |top-level site| return a [=WebDriver error=] with [=WebDriver error code=] [=unsupported operation=].
1. If |embedded origin| is [=same site=] with |top-level site| return a [=WebDriver error=] with [=WebDriver error code=] [=unsupported operation=].
1. If |blocked| is `true`, then:
1. Run an [=implementation-defined=] set of steps to ensure that |embedded site| does not have access to its [=unpartitioned data=] when loaded in a [=third party context=] on |top-level site|.
1. Run an [=implementation-defined=] set of steps to ensure that |embedded origin| does not have access to its [=unpartitioned data=] when loaded in a [=third party context=] on |top-level site|.
1. Otherwise, if |blocked| is `false`, then:
1. Run an [=implementation-defined=] set of steps to ensure that |embedded site| has access to its [=unpartitioned data=] when loaded in a [=third party context=] on |top-level site|.
1. Run an [=implementation-defined=] set of steps to ensure that |embedded origin| has access to its [=unpartitioned data=] when loaded in a [=third party context=] on |top-level site|.
1. If the above [=implementation-defined=] step of steps resulted in failure, return a [=WebDriver error=] with [=WebDriver error code=] [=unknown error=].
1. Return [=success=] with data `null`.

Expand Down