Skip to content

Commit

Permalink
Merge pull request #118 from WICG/cammie-branch1
Browse files Browse the repository at this point in the history
Update spec.bs to Change From Per-Origin to Per-Site Budgets
  • Loading branch information
pythagoraskitty committed Oct 3, 2023
2 parents 5c06564 + b1ad438 commit edd815c
Showing 1 changed file with 21 additions and 20 deletions.
41 changes: 21 additions & 20 deletions spec.bs
Original file line number Diff line number Diff line change
Expand Up @@ -727,53 +727,53 @@ On the other hand, methods for getting data from the [=shared storage database=]

#### Navigation Entropy Budget #### {#nav-budget}

If a user activates a [=fenced frame=] whose {{FencedFrameConfig}} was generated by {{WindowSharedStorage/selectURL()}} and thereby initiates a [=top-frame=] [=navigate|navigation=], this will reveal to the landing page that its [=/URL=] was selected, which is a leak in [=entropy bits=] of up to logarithm base 2 of the number of input [=/URLs=] for the call to {{WindowSharedStorage/selectURL()}}. To mitigate this, a [=user agent=] will set a per-[=calling origin=] [=navigation entropy allowance=].
If a user activates a [=fenced frame=] whose {{FencedFrameConfig}} was generated by {{WindowSharedStorage/selectURL()}} and thereby initiates a [=top-frame=] [=navigate|navigation=], this will reveal to the landing page that its [=/URL=] was selected, which is a leak in [=entropy bits=] of up to logarithm base 2 of the number of input [=/URLs=] for the call to {{WindowSharedStorage/selectURL()}}. To mitigate this, a [=user agent=] will set a per-[=calling site=] [=navigation entropy allowance=].

A <dfn>calling origin</dfn> for {{WindowSharedStorage/selectURL()}} is the [=url/origin=] of an [=environment=] that makes a {{WindowSharedStorage/selectURL()}} call.
A <dfn>calling site</dfn> for {{WindowSharedStorage/selectURL()}} is the [=site=] resulting from running [=obtain a site=] with the [=url/origin=] of an [=environment=] that makes a {{WindowSharedStorage/selectURL()}} call.

A <dfn>navigation entropy allowance</dfn> is a maximum allowance of [=entropy bits=] that are permitted to leak via [=fenced frames=] initiating [=top-frame=] [=navigate|navigations=] during a given [=navigation budget epoch=] for a given calling [=calling origin=]. This [=navigation entropy allowance|allowance=] is defined by the [=user agent=] and is [=calling origin=]-agnostic.
A <dfn>navigation entropy allowance</dfn> is a maximum allowance of [=entropy bits=] that are permitted to leak via [=fenced frames=] initiating [=top-frame=] [=navigate|navigations=] during a given [=navigation budget epoch=] for a given calling [=calling site=]. This [=navigation entropy allowance|allowance=] is defined by the [=user agent=] and is [=calling site=]-agnostic.

A [=user agent=] will define a fixed predetermined [=duration=] <dfn>navigation budget lifetime</dfn>.

An <dfn>navigation budget epoch</dfn> is any interval of time whose [=duration=] is the [=navigation budget lifetime=].

To keep track of how this [=navigation entropy allowance=] is used, the [=user agent=] uses a <dfn>shared storage navigation budget table</dfn>, which is a [=map=] of [=calling origins=] to [=navigation entropy ledgers=].
To keep track of how this [=navigation entropy allowance=] is used, the [=user agent=] uses a <dfn>shared storage navigation budget table</dfn>, which is a [=map=] of [=calling sites=] to [=navigation entropy ledgers=].

An <dfn>navigation entropy ledger</dfn> is a [=/list=] of [=bit debits=].

A <dfn>bit debit</dfn> is a [=struct=] containing a {{double}} <dfn for="bit debit">bits</dfn>, indicating a value in [=entropy bits=], along with a {{DOMHighResTimeStamp}} <dfn for="bit debit">timestamp</dfn> (from the [=Unix Epoch=]).

[=Bit debits=] whose [=bit debit/timestamps=] precede the start of the current [=navigation budget epoch=] are said to be <dfn for="bit debit">expired</dfn>.

When a leak occurs, its value in [=entropy bits=] is calculated and stored for that [=calling origin=], along with the current time as a [=bit debit/timestamp=], together as a [=bit debit=] in the [=shared storage navigation budget table=].
When a leak occurs, its value in [=entropy bits=] is calculated and stored for that [=calling site=], along with the current time as a [=bit debit/timestamp=], together as a [=bit debit=] in the [=shared storage navigation budget table=].

A [=calling origin=]'s <dfn for="calling origin">remaining navigation budget</dfn> is the [=navigation entropy allowance=] minus any [=bit debits=] whose [=bit debit/timestamps=] are within the current [=navigation budget epoch=].
A [=calling site=]'s <dfn for="calling site">remaining navigation budget</dfn> is the [=navigation entropy allowance=] minus any [=bit debits=] whose [=bit debit/timestamps=] are within the current [=navigation budget epoch=].

{{WindowSharedStorage/selectURL()}}'s argument "`urls`" is its <dfn for=selectURL>input URL list</dfn>.

When an [=calling origin=] has insufficient [=calling origin/remaining navigation budget=], {{WindowSharedStorage/selectURL()}} will return a {{SharedStorageResponse}} (i.e. either a {{FencedFrameConfig}} or an opaque [=/URL=]) for the {{SharedStorageUrlWithMetadata/url}} in the {{SharedStorageUrlWithMetadata}} at the [=default index=] in its [=selectURL/input URL list=].
When a [=calling site=] has insufficient [=calling site/remaining navigation budget=], {{WindowSharedStorage/selectURL()}} will return a {{SharedStorageResponse}} (i.e. either a {{FencedFrameConfig}} or an opaque [=/URL=]) for the {{SharedStorageUrlWithMetadata/url}} in the {{SharedStorageUrlWithMetadata}} at the [=default index=] in its [=selectURL/input URL list=].

The <dfn>default index</dfn> for a call to {{WindowSharedStorage/selectURL()}} is implementation-defined in such a way that it is independent from the result of the associated {{SharedStorageSelectURLOperation}}'s "`run`" method.

<div class="example">
The [=default index=] could be defined to be 0.

In this case, whenever the {{SharedStorageSelectURLOperation}}'s "`run`" method encounters an error, or whenever there is insufficient [=calling origin/remaining navigation budget=], the "`run`" method would return 0, and hence {{WindowSharedStorage/selectURL()}} would return a {{SharedStorageResponse}} for the first {{SharedStorageUrlWithMetadata/url}} in its [=selectURL/input URL list=].
In this case, whenever the {{SharedStorageSelectURLOperation}}'s "`run`" method encounters an error, or whenever there is insufficient [=calling site/remaining navigation budget=], the "`run`" method would return 0, and hence {{WindowSharedStorage/selectURL()}} would return a {{SharedStorageResponse}} for the first {{SharedStorageUrlWithMetadata/url}} in its [=selectURL/input URL list=].
</div>

<div class="example">
The [=default index=] could be defined to be [=selectURL/input URL list=]'s [=list/size=] minus 1.

In this case, whenever the {{SharedStorageSelectURLOperation}}'s "`run`" method encounters an error, or whenever there is insufficient [=calling origin/remaining navigation budget=], {{WindowSharedStorage/selectURL()}} would return a {{SharedStorageResponse}} for the last {{SharedStorageUrlWithMetadata/url}} in its [=selectURL/input URL list=].
In this case, whenever the {{SharedStorageSelectURLOperation}}'s "`run`" method encounters an error, or whenever there is insufficient [=calling site/remaining navigation budget=], {{WindowSharedStorage/selectURL()}} would return a {{SharedStorageResponse}} for the last {{SharedStorageUrlWithMetadata/url}} in its [=selectURL/input URL list=].
</div>

<div algorithm>
To <dfn>determine remaining navigation budget</dfn>, given an [=environment settings object=] |environment| and a calling [=calling origin=] |origin|, run the following steps:
To <dfn>determine remaining navigation budget</dfn>, given an [=environment settings object=] |environment| and a [=calling site=] |site|, run the following steps:

1. If |origin| is [=opaque origin|opaque=], return undefined.
1. If |site| is an [=opaque origin=], return undefined.
1. Let |maxBits| be the [=user agent=]'s [=navigation entropy allowance=].
1. If the [=user agent=]'s [=shared storage navigation budget table=] does not [=map/contain=] |origin|, then return |maxBits|.
1. Otherwise, let |ledger| be [=user agent=]'s [=shared storage navigation budget table=][|origin|].
1. If the [=user agent=]'s [=shared storage navigation budget table=] does not [=map/contain=] |site|, then return |maxBits|.
1. Otherwise, let |ledger| be [=user agent=]'s [=shared storage navigation budget table=][|site|].
1. Let |debitSum| be 0.
1. [=map/iterate|For each=] [=list/item=] |bitDebit| in |ledger|, do the following steps:
1. Let |debit| be |bitDebit|'s [=bit debit/bits=].
Expand Down Expand Up @@ -803,11 +803,11 @@ On the other hand, methods for getting data from the [=shared storage database=]
1. If |navigable| is not a [=navigable/traversable navigable=], return.
1. Let |node| be |sourceDocument|'s [=node navigable=].
1. While |node| is not null:
1. If |node| has a "fenced frame config struct":
1. Let |origin| be |node|'s [=active document=]'s [=document/origin=].
1. Let |site| be the result of running [=obtain a site=] with |node|'s [=active document=]'s [=document/origin=].
1. If |node| has a "fenced frame config struct" and |site| is not an [=opaque origin=], perform the following steps:
1. Let |pendingBits| be |node|'s "fenced frame config struct"'s [=pending shared storage budget debit=].
1. If |pendingBits| is greater than 0 and if "fenced frame config struct"'s [=has navigated=] is false, run the following steps:
1. Let |ledger| be [=user agent=]'s [=shared storage navigation budget table=][|origin|].
1. Let |ledger| be [=user agent=]'s [=shared storage navigation budget table=][|site|].
1. Let |bitDebit| be a new [=bit debit=].
1. Set |bitDebit|'s [=bit debit/bits=] to |pendingBits|.
1. Let |currentTime| be the [=/current wall time=].
Expand Down Expand Up @@ -964,7 +964,8 @@ On the other hand, methods for getting data from the [=shared storage database=]
1. Let |indexPromise| be the result of running [=get the select-url result index=], given |worklet|, |name|, |urlList|, and |options|.
1. [=Upon fulfillment=] of |indexPromise|, perform the following steps:
1. Let |resultIndex| be the numerical value of |indexPromise|.
1. Let |remainingBudget| be the result of running [=determine remaining navigation budget=] with |environment| and |document|'s [=url/origin=].
1. Let |site| be the result of running [=obtain a site=] with |document|'s [=url/origin=].
1. Let |remainingBudget| be the result of running [=determine remaining navigation budget=] with |environment| and |site|.
1. [=Assert=] that |remainingBudget| is not undefined.
1. Let |pendingBits| be the logarithm base 2 of |urlList|'s [=list/size=].
1. If |pendingBits| is greather than |remainingBudget|, set |resultIndex| to [=default index=].
Expand Down Expand Up @@ -1165,12 +1166,12 @@ On the other hand, methods for getting data from the [=shared storage database=]
1. If |context|'s [=active window=]'s [=associated document=] is not [=fully active=], return a [=promise rejected=] with a {{TypeError}}.
1. Let |environment| be |context|'s [=active window=]'s [=relevant settings object=].
1. If the result of running [=determine whether shared storage is allowed=] on |environment| is false, return a [=promise rejected=] with a {{TypeError}}.
1. Let |origin| be |context|'s [=active document=]'s [=document/origin=].
1. [=Assert=] that |origin| is not [=opaque origin|opaque=].
1. Let |site| be the result of running [=obtain a site=] with |context|'s [=active document=]'s [=document/origin=].
1. [=Assert=] that |site| is not an [=opaque origin=].
1. Let |queue| be |context|'s associated [=shared storage database|database=]'s [=shared storage database/shared storage database queue=].
1. Let |realm| be the [=current realm=].
1. [=Enqueue the following steps=] on |queue|:
1. Let |remainingBudget| be the result of running [=determine remaining navigation budget=] with |origin|.
1. Let |remainingBudget| be the result of running [=determine remaining navigation budget=] with |site|.
1. [=Assert=] that |remainingBudget| is not undefined.
1. Resolve [=queue a global task=] on the [=DOM manipulation task source=], given |realm|'s [=global object=], to resolve |promise| with |remainingBudget|.
1. Return |promise|.
Expand Down

0 comments on commit edd815c

Please sign in to comment.