diff --git a/spec.bs b/spec.bs
index b80e583..56abdeb 100644
--- a/spec.bs
+++ b/spec.bs
@@ -100,6 +100,7 @@ spec: html; urlPrefix: https://html.spec.whatwg.org/multipage/
urlPrefix: document-sequences.html
text: valid navigable target name or keyword; url: valid-navigable-target-name-or-keyword
text: the rules for choosing a navigable; url: the-rules-for-choosing-a-navigable
+ text: destroy a child navigable; url: destroy-a-child-navigable
urlPrefix: dom.html
text: categories; url: concept-element-categories
text: contexts in which this element can be used; url: concept-element-contexts
@@ -188,6 +189,7 @@ spec: html; urlPrefix: https://html.spec.whatwg.org/multipage/
text: sequential navigation search algorithm; url: sequential-navigation-search-algorithm
urlPefix: infrastructure.html
text: immediately; url: immediately
+ text: HTML element removing steps; url: html-element-removing-steps
urlPrefix: nav-history-apis.html
for: Window
text: navigable; url: window-navigable
@@ -212,6 +214,9 @@ spec: html; urlPrefix: https://html.spec.whatwg.org/multipage/
text: fire a click event; url: fire-a-click-event
urlPrefix: urls-and-fetching.html
text: about:srcdoc; url: about:srcdoc
+ urlPrefix: iframe-embed-object.html
+ for: iframe
+ text: HTML iframe element removing steps; url: the-iframe-element:html-element-removing-steps
spec: fetch; urlPrefix: https://fetch.spec.whatwg.org/
type: dfn
text: queue a cross-origin embedder policy CORP violation report; url: queue-a-cross-origin-embedder-policy-corp-violation-report
@@ -483,8 +488,13 @@ attribute.
- When a <{fencedframe}> element is [=removed from a document=], the user agent
TODO:
- destroy the nested traversable
.
+ When a <{fencedframe}> element is [=removed from a document=], the user agent must run the
+ following steps:
+
+ 1.
TODO: destroy the nested traversable.
+
+ 1. [=In parallel=], [=recalculate the untrusted network status of all fenced frame descendants=]
+ given the {{Document}}'s [=node navigable=]'s [=navigable/top-level traversable=].
The config IDL attribute getter steps are to return
@@ -849,6 +859,19 @@ a reporting destination=] through the reference it kept, it will handle all of t
stored in the [=list=]. If the destination is never finalized, then the pending events will never
be sent.
+An untrusted network status is either "`enabled`", "`disabled for this
+tree`", or "`disabled for this tree and fenced
+subtrees`".
+
+Note: [=untrusted network status/Disabled for this tree=] is not the final network cutoff state. It
+is an intermediate state where every frame within the frame tree that is not across a fenced frame
+boundary has had its network access revoked, but at least one sub-fenced frame tree still has
+network access. It does not get special API access at this stage as any information it gets access
+to can still be exfiltrated via the sub-fenced frame with network access. Once all sub-fenced frames
+have also had their untrusted network disabled, the fenced frame's status will switch to the final
+[=untrusted network status/disabled for this tree and fenced subtrees=] state.
+
In order to
finalize a reporting destination, given a [=fencedframetype/fenced
frame reporting map=] |reporting map|, a {{FenceReportingDestination}} |destination|, an
@@ -1224,17 +1247,18 @@ A
fenced frame config is a [=struct=] with the following [=str
:
visibility
:: a [=fencedframeconfig/visibility=]
- Note: When non-null, this is a [=list=] of [=policy-controlled features=] that the generator of
- this config relies on exclusively being enabled inside the <{fencedframe}> that navigates to
- this config. Specifically, each feature in this list
must be
- enabled by the <{fencedframe}>'s [=fenced navigable container/fenced navigable=]'s
- [=Document/permissions policy=]'s [=permissions policy/inherited policy=] when navigating to
- this config for the navigation to succeed. The features in this list are not force-enabled, but
- rather are used to check that the embedder environment that influences the aforementioned
- [=permissions policy/inherited policy=] is relaxed enough to support these essential features.
- If the [=inherited policy for a feature|inherited policy value=] for any of these features is
- "`Disabled`", the navigation to this config will fail. Any [=policy-controlled feature=] *not*
- in this list will not be "`Disabled`" in the <{fencedframe}> that navigates to this config.
+ Note: When non-null, this is a [=list=] of [=policy-controlled features=] that the generator
+ of this config relies on exclusively being enabled inside the <{fencedframe}> that navigates
+ to this config. Specifically, each feature in this list
must be
+ enabled by the <{fencedframe}>'s [=fenced navigable container/fenced navigable=]'s
+ [=Document/permissions policy=]'s [=permissions policy/inherited policy=] when navigating to
+ this config for the navigation to succeed. The features in this list are not force-enabled,
+ but rather are used to check that the embedder environment that influences the aforementioned
+ [=permissions policy/inherited policy=] is relaxed enough to support these essential
+ features. If the [=inherited policy for a feature|inherited policy value=] for any of these
+ features is "`Disabled`", the navigation to this config will fail. Any [=policy-controlled
+ feature=] *not* in this list will not be "`Disabled`" in the <{fencedframe}> that navigates
+ to this config.
:
fenced frame reporting metadata
:: null, or a [=struct=] with the following [=struct/items=]:
@@ -1266,16 +1290,16 @@ A
fenced frame config is a [=struct=] with the following [=str
:
is ad component
:: A [=boolean=], initially false.
+ Note: When true, this [=fenced frame config=] represents an ad component. An ad component can
+ be used to construct ads composed of multiple pieces. See the
Protected
+ Audience explainer. For an ad component, event reporting is handled differently. See the
Fenced
+ Frame Ads Reporting explainer that describes this.
+
:
cross-origin reporting allowed
:: A [=boolean=], initially false.
-
- Note: When true, this [=fenced frame config=] represents an ad component. An ad component can be
- used to construct ads composed of multiple pieces. See the
Protected
- Audience explainer. For an ad component, event reporting is handled differently. See the
Fenced
- Frame Ads Reporting explainer that describes this.
The [=fenced frame config instance=] [=struct=]
@@ -1322,8 +1346,19 @@ A
fenced frame config instance is a [=struct=] with the follow
:
is ad component
:: A [=boolean=]
- :
has disabled untrusted network
- :: A [=boolean=], initially false.
+ :
untrusted network status
+ :: An [=fencedframetype/untrusted network status=], initially [=untrusted network
+ status/enabled=].
+
+ :
on network disabled promises
+ :: A [=map=] whose [=map/keys=] are [=global objects=] and [=values=] are [=lists=] of
+ {{Promise|Promises}}, initially empty.
+
+ Note: This stores various {{Promise|Promises}} from various globals that were created during
+ {{Fence/disableUntrustedNetwork()}}. We store them here so that we can resolve all of them at
+ once when the <{fencedframe}> and its descendant fenced frames have their network access fully
+ revoked (i.e., the [=fenced frame config instance/untrusted network status=] is [=untrusted
+ network status/disabled for this tree and fenced subtrees=]).
:
cross-origin reporting allowed
:: A [=boolean=], initially false.
@@ -1415,8 +1450,11 @@ A
fenced frame config instance is a [=struct=] with the follow
: [=fenced frame config instance/cross-origin reporting allowed=]
:: |config|'s [=fenced frame config/cross-origin reporting allowed=]
- : [=fenced frame config instance/has disabled untrusted network=]
- :: false
+ : [=fenced frame config instance/untrusted network status=]
+ :: [=untrusted network status/enabled=]
+
+ : [=fenced frame config instance/on network disabled promises=]
+ :: A empty [=map=].
Each [=browsing context=] has a fenced frame config instance,
@@ -1937,8 +1975,11 @@ Several APIs specific to fenced frames are defined on the {{Fence}} interface.
1. Let |p| be [=a new promise=].
- 1. Let |instance| be [=this=]'s [=relevant global object=]'s [=Window/browsing context=]'s
- [=browsing context/fenced frame config instance=].
+ 1. Let |context| be [=this=]'s [=relevant global object=]'s [=Window/browsing context=].
+
+ 1. If |context| is null, then throw a {{SecurityError}} {{DOMException}}.
+
+ 1. Let |instance| be |context|'s [=browsing context/fenced frame config instance=].
1. If the [=relevant settings object=]'s [=environment settings object/origin=] and
|instance|'s [=fenced frame config instance/mapped url=]'s [=url/origin=] are not [=same
@@ -1950,32 +1991,109 @@ Several APIs specific to fenced frames are defined on the {{Fence}} interface.
1. Let |global| be [=this=]'s [=relevant global object=].
+ 1. Let |settings| be [=this=]'s [=relevant settings object=].
+
1. Run the following steps [=in parallel=]:
1. Let |fencedFrameNonce| be |instance|'s [=fenced frame config instance/partition nonce=].
- 1. Let |credentiallessNonce| be
+ 1. Let |credentiallessNonce| be |global|'s [=page credentialless nonce=].
- Issue: the page credentialless nonce
- (WICG/fenced-frame#191)
+ 1. Invoke [=revoke network for a partition nonce=] on |fencedFrameNonce| with |settings|.
- 1. Invoke [=revoke network for a partition nonce=] on |fencedFrameNonce|.
+ 1. If |credentiallessNonce| is non-null, invoke [=revoke network for a partition nonce=] on
+ |credentiallessNonce| with |settings|.
- 1. Invoke [=revoke network for a partition nonce=] on |credentiallessNonce|.
+ 1. Set |instance|'s [=fenced frame config instance/untrusted network status=] to [=untrusted
+ network status/disabled for this tree=].
- 1. Set |instance|'s [=fenced frame config instance/has disabled untrusted network=] to true.
+ 1. Let |promises| be |instance|'s [=fenced frame config instance/on network disabled
+ promises=].
- 1. Wait on all nested fenced frames to disable network too.
+ 1. If |promises|[|global|] [=map/exists=], [=list/append=] |p| to |promises|[|global|].
- Issue: Spec this waiting more formally.
- (WICG/fenced-frame#151)
+ Otherwise, [=map/set=] |promises|[|global|] to the [=list=] « |p| ».
- 1. [=Queue a global task=] on the [=DOM manipulation task source=] given |global|, to
- [=resolve=] |p| with {{undefined}}.
+ 1. [=Recalculate the untrusted network status of all fenced frame descendants=] given
+ |global|'s [=Window/browsing context=]'s [=browsing context/top-level traversable=].
1. Return |p|.
+
+ To recalculate the untrusted network status of all fenced frame descendants given a
+ [=top-level traversable=] |topLevelTraversable|, run these steps:
+
+ 1. [=Assert=]: this is running [=in parallel=].
+
+ 1. Let |navigables| be |topLevelTraversable|'s [=navigable/active document=]'s
+ [=Document/inclusive descendant navigables=] with [=inclusive-dn-unfenced|unfenced=] set to
+ true.
+
+ 1. Let |navigablesWithNetworkChildren| be a [=set=] of [=fenced navigable container/fenced
+ navigables=], initially empty.
+
+ 1. [=iteration/While=] |navigables| is not [=stack/empty=]:
+
+ 1. Let |currentNavigable| be the result of [=stack/pop|popping=] from |navigables|.
+
+ 1. If |currentNavigable| is not a [=fenced navigable container/fenced navigable=], then
+ [=iteration/continue=].
+
+ 1. Let |config| be |currentNavigable|'s [=navigable/active browsing context=]'s [=browsing
+ context/fenced frame config instance=].
+
+ 1. If |config|'s [=fenced frame config instance/untrusted network status=] is [=untrusted
+ network status/disabled for this tree and fenced subtrees=], then [=iteration/continue=].
+
+ 1. Let |networkCutoffReady| be true if |navigablesWithNetworkChildren| does not [=set/contain=]
+ |currentNavigable| and |config|'s [=fenced frame config instance/untrusted network status=]
+ is [=untrusted network status/disabled for this tree=], false otherwise.
+
+ Note: A [=fenced navigable container/fenced navigable=] is added to
+ |navigablesWithNetworkChildren| when it is the unfenced ancestor of another fenced frame
+ that is determined to not be ready for network cutoff.
+
+ 1. If |networkCutoffReady| is true:
+
+ 1. Set |config|'s [=fenced frame config instance/untrusted network status=] to [=untrusted
+ network status/disabled for this tree and fenced subtrees=].
+
+ Note: Any APIs gated on untrusted network being disabled are now immediately able to be
+ used at this point, even before the promises finish resolving.
+
+ 1. [=map/For each=] |global| → |promises| in |config|'s [=fenced frame config instance/on
+ network disabled promises=]:
+
+ 1. [=list/For each=] |promise| in |promises|:
+
+ 1. [=Queue a global task=] on the [=DOM manipulation task source=] given |global|, to
+ [=resolve=] |promise| with {{undefined}}.
+
+ 1. [=map/Clear=] |config|'s [=fenced frame config instance/on network disabled promises=].
+
+ 1. Otherwise:
+ 1. Let |ancestorFencedRoot| be |currentNavigable|'s [=traversable navigable/unfenced
+ parent=]'s [=navigable/traversable navigable=].
+
+ 1. If |ancestorFencedRoot| is a [=fenced navigable container/fenced navigable=],
+ [=set/append=] |ancestorFencedRoot| to |navigablesWithNetworkChildren|.
+
+
+
+ Rewrite the <{iframe}> element's [=iframe/HTML iframe element removing steps=] to read:
+
+ The <{iframe}> [=HTML element removing steps=], given |removedNode|, are:
+
+ 1. Let |topLevelTraversable| be |removedNode| [=navigable container/content navigable=]'s
+ [=navigable/top-level traversable=].
+
+ 1. [=Destroy a child navigable=] given |removedNode|.
+
+ 1. [=In parallel=], [=recalculate the untrusted network status of all fenced frame descendants=]
+ given |topLevelTraversable|.
+
+
A user agent has an associated network revocation nonce set, which is a [=set=] of
[=partition nonces=], and a network revocation exemption map, which is a [=map=] whose
[=map/keys=] are [=partition nonces=] and [=map/values=] are [=sets=] of [=URLs=].
@@ -1989,12 +2107,12 @@ Issue: This will require a RFC to add a test-only function to the WPT web driver
To revoke network for a partition nonce using a [=fenced frame config
- instance/partition nonce=] |nonce|, run these steps:
+ instance/partition nonce=] |nonce| given a [=relevant settings object=] |settings|, run these
+ steps:
1. [=set/Append=] |nonce| to the user agent's [=network revocation nonce set=].
- 1. [=fetch group/terminated|Terminate=] [=this=]'s [=relevant settings object=]'s
- [=fetch/fetch group=].
+ 1. [=fetch group/terminated|Terminate=] |settings|'s [=fetch/fetch group=].
@@ -2027,8 +2145,14 @@ The network revocation mechanism requires the following monkeypatches to the [[F
Add "[=must be blocked due to a revoked partition nonce=]" to the conditions after
"should request be blocked by Content Security Policy".
+
+ Issue: This needs to be passed in both the fenced frame nonce as well as the iframe credentialless
+ nonce, if it exists.
+ (
WICG/fenced-frame#191)
+The network revocation mechanism requires the following monkeypatches to the [[HTML]] Standard.
+
New [=request=] [=request/destination=]
The processing model of a <{fencedframe}>'s navigation request deviates from that of the normal
@@ -2733,12 +2857,12 @@ the fenced frame boundary, which is a privacy leak. To avoid this, we effectivel
Modify step 3 of the [=currently focused area of a top-level traversable=] algorithm to read:
- 3. While |candidate|'s [=focused area=] is either a [=navigable container=] with a non-null
- [=navigable container/content navigable=] or a [=fenced navigable container=] with a non-null
- [=fenced navigable container/fenced navigable=]: set |candidate| to the [=navigable/active
- document=] of either that [=navigable container=]'s [=navigable container/content navigable=]
- or that [=fenced navigable container=]'s [=fenced navigable container/fenced navigable=],
- whichever is non-null.
+ 3. [=iteration/While=] |candidate|'s [=focused area=] is either a [=navigable container=] with a
+ non-null [=navigable container/content navigable=] or a [=fenced navigable container=] with a
+ non-null [=fenced navigable container/fenced navigable=]: set |candidate| to the
+ [=navigable/active document=] of either that [=navigable container=]'s [=navigable
+ container/content navigable=] or that [=fenced navigable container=]'s [=fenced navigable
+ container/fenced navigable=], whichever is non-null.
@@ -2954,7 +3078,7 @@ CORP violation report=] algorithm, as leaving it unfenced may cause a privacy le
1. Let |current navigable| be |sourceDocument|'s [=node navigable=].
- 1. While |current navigable| is not null:
+ 1. [=iteration/While=] |current navigable| is not null:
1. [=map/iterate|For each=] |type| → |data| of |current navigable|'s [=navigable/active
document=]'s [=Document/automatic beacon data map=]: