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

[Spec] Add sandbox attribute + handling #180

Merged
merged 7 commits into from
Aug 26, 2024
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
147 changes: 124 additions & 23 deletions spec.bs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ spec: html; urlPrefix: https://html.spec.whatwg.org/multipage/
text: queue a cross-origin embedder policy inheritance violation; url: queue-a-cross-origin-embedder-policy-inheritance-violation
text: determine navigation params policy container; url: determining-navigation-params-policy-container
text: cross-origin opener policy enforcement result; url: coop-enforcement-result
text: determine the creation sandboxing flags; url: determining-the-creation-sandboxing-flags
text: iframe sandboxing flag set; url: iframe-sandboxing-flag-set
for: cross-origin opener policy enforcement result
text: needs a browsing context group switch; url: coop-enforcement-bcg-switch
urlPrefix: dom.html
Expand Down Expand Up @@ -145,6 +147,7 @@ spec: html; urlPrefix: https://html.spec.whatwg.org/multipage/
text: navigable; url: navigation-params-navigable
text: origin; url: navigation-params-origin
text: COOP enforcement result; url: navigation-params-coop-enforcement-result
text: final sandboxing flag set; url: navigation-params-sandboxing
for: history handling behavior
text: replace; url: hh-replace
for: document state
Expand Down Expand Up @@ -411,6 +414,7 @@ interface HTMLFencedFrameElement : HTMLElement {
[CEReactions] attribute FencedFrameConfig? config;
[CEReactions] attribute DOMString width;
[CEReactions] attribute DOMString height;
[SameObject, PutForwards=value] readonly attribute DOMTokenList sandbox;
[CEReactions] attribute DOMString allow;
};
</xmp>
Expand All @@ -424,6 +428,22 @@ Descendants of <{fencedframe}> elements represent nothing.
Each <{fencedframe}> has a <dfn for=fencedframe>config</dfn>, which is either a
{{FencedFrameConfig}} or null. It is initially null.

Each <{fencedframe}> has a <dfn for=fencedframe>fencedframe sandboxing flag set</dfn>, which is a
[=sandboxing flag set=]. Which flags in a [=fencedframe/fencedframe sandboxing flag set=] are set
at any particular time is determined by the <{fencedframe}> element's <{fencedframe/sandbox}>
attribute.

<div algorithm=determine-sandbox-flags-patch>
Modify the [=determine the creation sandboxing flags=] algorithm. Rewrite the second step in the
union to be the following 2 steps:

* If |embedder| is an <{iframe}> element, then: the flags set on |embedder|'s [=iframe sandboxing
flag set=].

* If |embedder| is a <{fencedframe}> element, then: the flags set on |embedder|'s [=fencedframe/
fencedframe sandboxing flag set=].
</div>

<div algorithm=insertion>
When a <{fencedframe}> element |element| is [=node is inserted into a document|inserted into a
document=] whose [=Document/browsing context=] is non-null, run these steps:
Expand All @@ -433,7 +453,8 @@ Each <{fencedframe}> has a <dfn for=fencedframe>config</dfn>, which is either a

1. Set |nested traversable|'s [=navigable/loading mode=] to "`fencedframe`".

1. <span class=XXX>Parse the sandbox attributes, once it exists</span>
1. If |element| has a <{fencedframe/sandbox}> attribute, then [=parse a sandboxing directive=]
given the attribute's value and |element|'s [=fencedframe/fencedframe sandboxing flag set=].

Issue: It's not necessary to call the <a
href=https://html.spec.whatwg.org/multipage/browsing-the-web.html#url-and-history-update-steps>URL
Expand Down Expand Up @@ -492,8 +513,46 @@ The <dfn element-attr for=fencedframe>allow</dfn> attribute, when specified, det
in the <{fencedframe}>'s [=fenced navigable container/fenced navigable=] is initialized. Its value
must be a [=serialized permissions policy=]. [[!PERMISSIONS-POLICY]]

The IDL attribute <dfn attribute for=HTMLFencedFrameElement>allow</dfn> must [=reflect=] the
respective content attribute of the same name.
The <dfn element-attr for=fencedframe>sandbox</dfn> attribute, when specified, enables a set of
extra restrictions on any content hosted by the <{fencedframe}>. Its value must be an [=unordered
set of unique space-separated tokens=] that are [=ASCII case-insensitive=]. The allowed values are:

* <{iframe/sandbox/allow-downloads}>
* <{iframe/sandbox/allow-forms}>
* <{iframe/sandbox/allow-modals}>
* <{iframe/sandbox/allow-orientation-lock}>
* <{iframe/sandbox/allow-pointer-lock}>
* <{iframe/sandbox/allow-popups}>
* <{iframe/sandbox/allow-popups-to-escape-sandbox}>
* <{iframe/sandbox/allow-presentation}>
* <{iframe/sandbox/allow-same-origin}>
* <{iframe/sandbox/allow-scripts}>
* <{iframe/sandbox/allow-top-navigation}>
* <{iframe/sandbox/allow-top-navigation-by-user-activation}>
* <{iframe/sandbox/allow-top-navigation-to-custom-protocols}>

The IDL attributes <dfn attribute for=HTMLFencedFrameElement>allow</dfn> and <dfn attribute
for=HTMLFencedFrameElement>sandbox</dfn> must [=reflect=] the respective content attribute of the
same name.

The supported tokens for {{HTMLFencedFrameElement/sandbox}}'s {{DOMTokenList}} are the allowed
values defined in the <{fencedframe/sandbox}> attribute and supported by the user agent.

<div algorithm=fencedframe-attribute-change>
The following [=attribute change steps=], given |element|, |localName|, <var ignore>oldValue</var>,
|value|, and |namespace| are used for all <{fencedframe}> elements:

1. [=Assert=]: |namespace| is the [=HTML namespace=].

1. If |localName| is <{fencedframe/sandbox}>, then:

1. If |value| is null, then [=set/empty=] |element|'s [=fencedframe/fencedframe sandboxing flag
set=].

1. Otherwise, run [=parse a sandboxing directive=] given the |value| and |element|'s
[=fencedframe/fencedframe sandboxing flag set=].

</div>

<h3 id=dimension-attributes>Dimension attributes</h3>

Expand Down Expand Up @@ -715,9 +774,6 @@ following [=struct/items=]:
:: a [=string=]
</dl>

An <dfn export for=fencedframetype>exhaustive set of sandbox flags</dfn> is a [=sandboxing flag
set=].

A <dfn export for=fencedframetype>pending event</dfn> is a [=struct=] with the following
[=struct/items=]:

Expand Down Expand Up @@ -1094,12 +1150,12 @@ A <dfn export>fenced frame config</dfn> is a [=struct=] with the following [=str
: <dfn>on navigate callback</dfn>
:: null, or a series of steps

: <dfn>effective sandbox flags</dfn>
: <dfn>effective sandboxing flags</dfn>
:: null, or a [=struct=] with the following [=struct/items=]:
: <dfn for="effective sandbox flags">value</dfn>
:: an [=fencedframetype/exhaustive set of sandbox flags=]
: <dfn for="effective sandboxing flags">value</dfn>
:: a [=sandboxing flag set=]

: <dfn for="effective sandbox flags">visibility</dfn>
: <dfn for="effective sandboxing flags">visibility</dfn>
:: a [=fencedframeconfig/visibility=]

: <dfn>effective enabled permissions</dfn>
Expand Down Expand Up @@ -1183,8 +1239,8 @@ A <dfn export>fenced frame config instance</dfn> is a [=struct=] with the follow
: <dfn>on navigate callback</dfn>
:: null, or a series of steps

: <dfn>effective sandbox flags</dfn>
:: null, or an [=fencedframetype/exhaustive set of sandbox flags=]
: <dfn>effective sandboxing flags</dfn>
:: null, or a [=sandboxing flag set=]

: <dfn>effective enabled permissions</dfn>
:: null, or a [=list=] of [=policy-controlled features=]
Expand Down Expand Up @@ -1233,9 +1289,9 @@ A <dfn export>fenced frame config instance</dfn> is a [=struct=] with the follow
: [=fenced frame config instance/on navigate callback=]
:: |config|'s [=fenced frame config/on navigate callback=]

: [=fenced frame config instance/effective sandbox flags=]
:: |config|'s [=fenced frame config/effective sandbox flags=] if null, otherwise |config|'s
[=fenced frame config/effective sandbox flags=]'s [=effective sandbox flags/value=]
: [=fenced frame config instance/effective sandboxing flags=]
:: |config|'s [=fenced frame config/effective sandboxing flags=] if null, otherwise |config|'s
[=fenced frame config/effective sandboxing flags=]'s [=effective sandboxing flags/value=]

: [=fenced frame config instance/effective enabled permissions=]
:: |config|'s [=fenced frame config/effective enabled permissions=] if null, otherwise
Expand Down Expand Up @@ -2832,6 +2888,22 @@ CORP violation report=] algorithm, as leaving it unfenced may cause a privacy le
navigable=], or the result of [=checking if unloading is user-canceled=] for |navigable|'s
[=navigable/active document=]'s [=Document/inclusive descendant navigables=] otherwise.

Add a step after step 22.8.2 (Let |finalSandboxFlags| be the [=set/union=]...) that reads:

3. If |sourceSnapshotParams|'s [=source snapshot params/target fenced frame config=] is not null,
and if |sourceSnapshotParams|'s [=source snapshot params/target fenced frame config=]'s
[=fenced frame config/effective sandboxing flags=] is not null, then set |finalSandboxFlags| to
the [=set/union=] of |finalSandboxFlags| and |sourceSnapshotParams|'s [=source snapshot
params/target fenced frame config=]'s [=fenced frame config/effective sandboxing flags=]'
[=effective sandboxing flags/value=].

Note: This ensures that the |finalSandboxFlags| are *at least* as restrictive as the [=fenced
frame config/effective sandboxing flags=] defined in the [=source snapshot params/target fenced
frame config=]. A separate check in the [=should navigation response to navigation request be
blocked by sandboxing flags?|blocked by sandboxing flags?=] algorithm will make sure that
|finalSandboxFlags| is not more restrictive than the [=fenced frame config/effective sandboxing
flags=].

<wpt>
/fenced-frame/before-unload.https.html
</wpt>
Expand Down Expand Up @@ -3298,16 +3370,18 @@ algorithms to achieve the outcomes described in the above explanatory content.
</div>

<div algorithm=attempt-populate-history-patches>
Modify [[HTML]]'s [=attempt to populate the history entry's document=] algorithm. Add a step
before the step inside the [=queue a task|queued task=] starting with "If
|failure| is true, then:" that reads:
Modify [[HTML]]'s [=attempt to populate the history entry's document=] algorithm. Add the
following conditions to step 6.4 (Otherwise, if any of the following are true:) that say:

* The result of [=should navigation response to navigation request be blocked by Permissions
Policy?=] given <var ignore>navigationParams</var> is "`Blocked`";

8. Otherwise, if the result of [=should navigation response to navigation request be blocked by
Permissions Policy?=] given <var ignore>navigationParams</var> is "`Blocked`", then set
|failure| to true.
* The result of [=should navigation response to navigation request be blocked by sandboxing
flags?=] given <var ignore>navigationParams</var> and <var ignore>sourceSnapshotParams</var> is
"`Blocked`";

Note: If this algorithm returns "`Blocked`", the pre-existing {{Document}} in the <{fencedframe}>
does not stick around; an error page will be loaded.
Note: If any of these algorithms returns "`Blocked`", the pre-existing {{Document}} in the
<{fencedframe}> does not stick around; an error page will be loaded.
</div>

<div algorithm=permissions-policy-block-request>
Expand Down Expand Up @@ -3359,6 +3433,33 @@ algorithms to achieve the outcomes described in the above explanatory content.
1. Return "`Allowed`."
</div>

<div algorithm>
<dfn>Should navigation response to navigation request be blocked by sandboxing flags?</dfn>

Given a [=navigation params=] (|navigationParams|) and a [=source snapshot params=]
(|sourceSnapshotParams|), this algorithm returns "`Blocked`" or "`Allowed`":

1. Let |navigable| be |navigationParams|'s [=navigation params/navigable=].

1. If |navigable| is not a [=fenced navigable container/fenced navigable=], then return
"`Allowed`".

1. Let |effectiveSandboxingFlags| be the |sourceSnapshotParams|'s [=source snapshot params/target
fenced frame config=]'s [=fenced frame config/effective sandboxing flags=].

1. If |navigationParams|'s [=navigation params/final sandboxing flag set=] is not a [=set/subset=]
of |effectiveSandboxingFlags|, then return "`Blocked`".

Note: This means that the [=navigation params/final sandboxing flag set=] cannot restrict a
feature that isn't already restricted in the [=fenced frame config instance/effective
sandboxing flags=], as the extra restrictions can be used as a communication channel. By this
point, the [=navigation params/final sandboxing flag set=] will already have been set to
something *at least* as restrictive as the [=fenced frame config instance/effective sandboxing
flags=].

1. Otherwise, return "`Allowed`".
</div>

<div algorithm=define-inherited-policy-in-container-patches>
Modify the [$Define an inherited policy for feature in container at origin$] algorithm to
read:
Expand Down
Loading