1. Introduction
This section is non-normative.
In
a
web
that
has
its
cookies
and
storage
partitioned
by
top-frame
site,
there
are
occasions
—
such
as
interest
group
based
advertising
as
provided
by
the
[Protected-Audience]
API,
or
Conversion
Lift
Measurements
)
—
when
it
would
be
useful
to
display
content
from
different
partitions
in
the
same
page.
This
can
only
be
done
in
a
privacy-preserving
way
if
the
Document
s
that
contain
data
from
different
partitions
are
isolated
from
each
other,
unable
to
communicate
despite
being
re
visually
composed
on
the
same
page.
iframe
elements
are
not
suitable
for
this,
since
they
offer
many
intentional
communication
channels
with
their
embedder.
This
specification
introduces
the
fencedframe
element,
a
new
element
to
embed
Document
s
on
a
page
that
explicitly
prevents
communication
between
the
Document
and
its
embedder.
This
specification
defines
the
new
element,
its
integration
with
the
rest
of
the
web
platform,
including
§ 3
HTML
Integration
and
§ 4
Interactions
with
other
specifications
,
and
its
supporting
primitives
like
FencedFrameConfig
,
which
is
the
major
input
to
the
fencedframe
in
place
of
normal
URLs
and
"
src
"
attributes.
Given
that
this
specification
defines
a
new
element
and
its
integration
with
the
rest
of
the
platform,
it
should
be
read
as
largely
a
monkeypatch
to
the
[HTML]
,
with
its
end
goal
to
be
merged
into
that
standard,
provided
there
is
adequate
cross-browser
support.
2.
The
fencedframe
element
- Categories :
-
Flow
content
.
- Phrasing content .
- Embedded content .
- Interactive content .
- Palpable content .
- Phrasing content .
- Contexts in which this element can be used :
- Where embedded content is expected.
- Content model :
- Nothing .
- Content attributes :
-
Global
attributes
width— Horizontal dimensionheight— Vertical dimension— Permissions policy to be applied to theallowfencedframe's contents - Accessibility considerations :
-
TODO
- DOM interface :
-
[
Exposed =Window ]interface :HTMLFencedFrameElement HTMLElement { [HTMLConstructor ](); [constructor CEReactions ]attribute FencedFrameConfig ?config ; [CEReactions ]attribute DOMString width ; [CEReactions ]attribute DOMString height ; [CEReactions ]attribute DOMString allow ; };
The
fencedframe
element
represents
its
fenced
navigable
.
Descendants
of
fencedframe
elements
represent
nothing.
Each
fencedframe
has
a
config
,
which
is
either
a
FencedFrameConfig
or
null.
It
is
initially
null.
fencedframe
element
element
is
inserted
into
a
document
whose
browsing
context
is
non-null,
run
these
steps:
-
Let nested traversable be the result of creating a new nested traversable for element .
-
Set nested traversable ’s loading mode to "
fencedframe". -
Parse the sandbox attributes, once it exists
It’s
not
necessary
to
call
the
URL
and
history
update
steps
as
we
do
during
usual
child
navigable
creation
or
top-level
traversable
creation
,
but
we
still
need
a
mechanism
to
initialize
History
.
length
in
the
new
navigable.
This
is
an
existing
issue
in
the
HTML
Standard:
https://github.com/whatwg/html/issues/9030
.
fencedframe
element
is
removed
from
a
document
,
the
user
agent
TODO: destroy the nested traversable
.
The
config
IDL
attribute
getter
steps
are
to
return
this
's
config
.
config
IDL
attribute
setter
steps
are:
-
-
Assert : this 's fenced navigable is null.
Note: This holds because when the element has been removed from the DOM, its removal steps immediately destroy the fenced navigable .
-
-
Let urn uuid be the given
FencedFrameConfig's urn . -
Let shared storage context be the given
FencedFrameConfig's sharedStorageContext . -
Navigate element ’s fenced navigable to urn uuid using element ’s node document , with historyHandling set to "
replace", referrerPolicy set to "no-referrer" , and shared storage context .Note: See § 3.7.3 Actual navigation changes for the
fencedframe-specific changes to the ordinary navigation flow.
The
allow
attribute,
when
specified,
determines
the
container
policy
that
will
be
used
when
the
permissions
policy
for
a
Document
in
the
fencedframe
's
fenced
navigable
is
initialized.
Its
value
must
be
a
serialized
permissions
policy
.
[PERMISSIONS-POLICY]
The
IDL
attribute
allow
must
reflect
the
respective
content
attribute
of
the
same
name.
2.1. Dimension attributes
This
section
details
monkeypatches
to
[HTML]
's
Dimension
attributes
section.
That
section
will
be
updated
to
include
fencedframe
in
the
list
of
elements
whose
own
width
and
height
dimension
attributes
have
the
same
author
requirements
that
apply
to
the
general
width
and
height
dimension
attributes
defined
in
[HTML]
.
Furthermore,
the
IDL
attributes
width
and
height
must
reflect
the
respective
content
attributes
of
the
same
name.
2.2. Fenced frame config mapping
Each traversable navigable has a fenced frame config mapping , which is a fenced frame config mapping .
Note:
This
mapping
is
consulted
during
navigation
,
and
written
to
by
what
we
colloquially
refer
to
as
URN-generating
APIs
or
config-generating
APIs
,
that
generate
both
urn
uuids
and
fenced
frame
configs
for
use
in
navigating
fencedframe
and
iframe
elements.
See
for
example,
the
[Protected-Audience]
API
and
[Shared-Storage]
specifications.
A fenced frame config mapping has three submappings:
- pending config mapping
-
a map whose keys are urn uuids and whose values are fenced frame configs
- finalized config mapping
-
a map whose keys are urn uuids and whose values are fenced frame configs
- nested config mapping
-
a map whose keys are urn uuids and whose values are fenced frame configs
Note:
The
purpose
of
pending
configs
is
to
enable
config-generating
APIs
to
resolve
configs
asynchronously
in
a
way
that
doesn’t
create
timing
side
channels,
i.e.,
the
pending
config
is
returned
to
the
web
platform
in
a
constant
amount
of
time,
before
any
computation
whose
duration
depends
on
cross-site
data.
Because
the
privacy
of
this
depends
on
the
web
platform
not
being
able
to
discern
when
a
pending
config
is
finalized,
it
is
important
that
all
visibilities
and
values
of
transparent
fields
do
not
change
from
the
pending
config
to
the
finalized
config,
given
that
they
can
be
inspected
through
FencedFrameConfig
's
getters.
Therefore,
a
FencedFrameConfig
that
is
created
and
exposed
to
the
web
platform
is
effectively
immutable
even
if
the
fenced
frame
config
represented
by
the
config
's
urn
is
technically
"pending",
and
will
finish
resolving
completely
later.
Each fenced frame config mapping has a maximum number of configs , which is implementation-defined. The maximum number of configs may be a non-negative number or infinity.
Note: It is important to specify the behavior of maximum number of configs because its semantics can interact with config-generating APIs in a privacy sensitive way.
At a high level, in order to store a fenced frame config in the fenced frame config mapping , the creator of the config must first store a pending config, and then turn the pending config into a finalized config. Those procedures are as follows:
-
Let pendingMapping be mapping ’s pending config mapping .
-
If the size of pendingMapping + the size of mapping ’s finalized config mapping ≥ mapping ’s maximum number of configs , return failure.
-
Let urn be a randomly generated urn uuid .
-
Set pendingMapping [ urn ] to config .
-
Return urn .
-
Let pendingMapping be mapping ’s pending config mapping .
-
Let finalizedMapping be mapping ’s finalized config mapping .
-
If pendingMapping [ urn ] does not exist , return failure.
-
Remove pendingMapping [ urn ].
-
Set finalizedMapping [ urn ] to config .
-
Let nestedMapping be mapping ’s nested config mapping .
-
If nestedConfigs is null, return.
-
For each urn → config of nestedConfigs :
-
Set nestedMapping [ urn ] to config .
-
-
Let nestedMapping be mapping ’s nested config mapping .
-
Let pendingMapping be mapping ’s pending config mapping .
-
Let finalizedMapping be mapping ’s finalized config mapping .
-
If nestedMapping [ urn ] exists , return its value.
-
If pendingMapping [ urn ] exists , wait until it does not exist .
-
If finalizedMapping [ urn ] exists , return its value.
-
Return failure.
2.3. Fenced frame configs
2.3.1. Introduction
This section is non-normative.
A
key
feature
of
the
fencedframe
element
is
that
web
platform
APIs
can
configure
the
behavior
of
the
frame
in
a
way
that
limits
the
ability
of
other
execution
contexts
to
modify
or
inspect
this
configuration,
for
security
and
privacy
reasons.
For
example,
the
[Protected-Audience]
API
performs
on-device
ad
auctions
over
cross-site
data,
and
it
is
important
that
the
ad
that
wins
the
auction
can
be
loaded
into
a
frame,
without
the
API
caller
knowing
which
ad
won
the
auction
or
being
able
to
manipulate
the
environment
in
which
the
ad
loads.
We
achieve
this
using
the
concept
of
a
"
fenced
frame
config
".
A
fenced
frame
config
is
a
collection
of
fields
that
can
be
loaded
into
fencedframe
elements
and
that
specifies
the
resulting
environments.
Fenced
frame
configs
can
only
be
created
by
specific
web
platform
APIs,
and
not
constructed
or
modified
by
script.
Their
fields
also
contain
"
visibilities
",
which
dictate
whether
the
field
should
be
"redacted"
when
inspected
through
the
FencedFrameConfig
interface.
Config-generating
APIs
like
the
[Protected-Audience]
and
[Shared-Storage]
APIs
must
specify
values
for
all
fields
of
their
fenced
frame
configs
in
order
to
ensure
that
they
have
considered
the
privacy
implications
of
each
field,
though
they
may
choose
to
set
the
values
to
null.
Each
time
a
fencedframe
navigates
to
a
fenced
frame
config
,
it
is
instantiated
as
a
new
fenced
frame
config
instance
,
which
governs
the
particular
browsing
context
group
inside
the
fenced
navigable
.
2.3.2. The fenced frame config struct
We now establish some preliminary types:
A
visibility
is
either
"
opaque
"
or
"
transparent
".
A size is a struct with the following items :
- width
-
a non-negative integer
- height
-
a non-negative integer
TODO: Consider different numeric types for these members.
An interest group descriptor is a struct with the following items :
An exhaustive set of sandbox flags is a sandboxing flag set .
A pending event is a struct with the following items :
A
fenced
frame
reporting
map
is
a
map
whose
keys
are
FenceReportingDestination
s
and
whose
values
are
either:
-
lists of pending events (which are used to represent events that need to be reported asynchronously, because the metadata has not been finalized yet); or
-
maps whose keys are strings and whose values are urls (which are used to represent the actual metadata once it is finalized).
Note: This representation is meant to allow config-generating APIs to reduce latency by resolving the values of reporting destinations asynchronously, after they’ve already constructed and returned the fenced frame config (and even after the config has been loaded, and event reports have been generated inside the fenced frame). When the config-generating API declares the fenced frame reporting map , they can mark certain destinations as pending using an empty list , and then maintain a reference to the map for later. If the fenced frame attempts to report an event to a destination while it is still pending, it stores the event in this list for later handling. When the config-generating API or its callback eventually finalizes a reporting destination through the reference it kept, it will handle all of the pending events stored in the list . If the destination is never finalized, then the pending events will never be sent.
FenceReportingDestination
destination
,
and
a
map
destination
map
whose
keys
are
strings
and
whose
values
are
urls
,
run
these
steps:
-
Assert that reporting map [ destination ] is a list (i.e., that destination ’s metadata has not yet been finalized).
-
Let pending event list be reporting map [ destination ].
-
Set reporting map [ destination ] to destination map .
-
For each pending event of pending event list :
-
Send a beacon with destination map , pending event ’s eventType , and pending event ’s eventData .
-
A fenced frame reporting metadata is a struct with the following items :
- fenced frame reporting map
- direct seller is seller
-
a boolean
A fenced frame reporter is a struct with the following items :
- fenced frame reporting metadata reference
-
a mutable reference to a fenced frame reporting metadata TODO: Handle pointers/references in a more spec-y way
- automatic beacon data
-
null, or a struct with the following items :
- eventData
-
a string
- destination
-
a list of
FenceReportingDestinations - once
-
a boolean
-
If destination map [ eventType ] does not exist , return.
-
Let destination url be destination map [ eventType ].
-
Optionally, return.
Note: This implementation-defined condition is intended to allow user agents to drop the beacon for a number of reasons, for example user opt-out or destination url ’s site not being enrolled .
-
Let request be a new request with the following properties:
- method
-
POST - URL
-
destination url
- header list
-
A new header list containing a header whose name is
"Content-Type"and value is"text/plain". - body
- client
-
null
- service-workers mode
-
"all"The default is
"all", so we technically don’t have to set anything here. We do in order to remind ourselves that it might be more appropriate to skip service workers here, like some other beacons . - origin
-
Get the origin from somewhere, like the implementation does .
- referrer
-
"no-referrer" - mode
-
"cors" - credentials mode
-
"omit"
-
Fetch request .
Note: This algorithm can be invoked from while in parallel or while on a
Document's main thread. To handle the in parallel invocation correctly, ordinarily we would invoke fetch with useParallelQueue set to true, but since we don’t pass in any of the optional response -handling algorithms, there is no need to do this.
FenceReportingDestination
destination
,
string
eventType
,
and
string
eventData
,
run
these
steps:
-
If destination is
"direct-seller":-
If reporter ’s fenced frame reporting metadata reference 's direct seller is seller is true, set destination to
"seller". -
Otherwise, set destination to
"component-seller".
-
-
Let reporting map be a reference to reporter ’s fenced frame reporting metadata reference 's fenced frame reporting map .
-
If reporting map [ destination ] does not exist , return.
-
If reporting map [ destination ] is a list :
-
Let newEvent be a new pending event with the following:
- destination
-
destination
- eventType
-
eventType
- eventData
-
eventData
-
Append newEvent to reporting map [ destination ].
-
Return.
Note: The pending event will be sent asynchronously.
-
-
Assert that reporting map [ destination ] is a map (i.e. that destination ’s metadata has been finalized).
-
Send a beacon with reporting map [ destination ], eventType , and eventData .
-
reporter event TODO: Fill this in
An exfiltration budget metadata is a struct with the following items :
- origin
-
an origin
- amount to debit
-
a non-negative valid floating point number
An exfiltration budget metadata reference is a struct with the following items :
- origin
-
an origin
- amount to debit reference
-
a mutable reference to a non-negative valid floating point number TODO: Handle pointers/references in a more specy-y way
A partition nonce is an implementation-defined value.
Note: This is similar to the network partition key used by Fetch .
A fenced frame config is a struct with the following items :
- mapped url
-
a struct with the following items :
- value
-
a URL
- visibility
- container size
-
null, or a size
- content size
-
null, or a struct with the following items :
- value
-
a size
- visibility
- interest group descriptor
-
null, or a struct with the following items :
- value
- visibility
- on navigate callback
-
null, or a series of steps
- effective sandbox flags
-
null, or a struct with the following items :
- value
- visibility
- effective enabled permissions
-
null, or a struct with the following items :
- value
- 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
fencedframethat navigates to this config. Specifically, each feature in this list must be enabled by thefencedframe's fenced navigable 's permissions policy 's 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 inherited policy is relaxed enough to support these essential features. If the 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 thefencedframethat navigates to this config. - fenced frame reporting metadata
-
null, or a struct with the following items :
- value
- visibility
- exfiltration budget metadata
-
null, or a struct with the following items :
- value
- visibility
- nested configs
-
null, or a struct with the following items :
- value
-
a list of fenced frame configs
- visibility
- embedder shared storage context
-
null, or a string
2.3.3. The fenced frame config instance struct
A fenced frame config instance is a struct with the following items :
- mapped url
-
a URL
- container size
-
null, or a size
- content size
-
null, or a size
- interest group descriptor
-
null, or an interest group descriptor
- on navigate callback
-
null, or a series of steps
- effective sandbox flags
-
null, or an exhaustive set of sandbox flags
- effective enabled permissions
-
null, or a list of policy-controlled features
- fenced frame reporter
-
null, or a fenced frame reporter
- exfiltration budget metadata reference
-
null, or an exfiltration budget metadata reference
- nested configs
-
null, or an map whose keys are urn uuids and whose values are fenced frame configs
- partition nonce
- embedder shared storage context
-
null, or a string
- mapped url
-
config ’s mapped url 's value
- container size
-
config ’s container size
- content size
-
config ’s content size if null, otherwise config ’s content size 's value
- interest group descriptor
-
config ’s interest group descriptor if null, otherwise config ’s interest group descriptor 's value
- on navigate callback
-
config ’s on navigate callback
- effective sandbox flags
-
config ’s effective sandbox flags if null, otherwise config ’s effective sandbox flags 's value
- effective enabled permissions
-
config ’s effective enabled permissions if null, otherwise config ’s effective enabled permissions 's value
- fenced frame reporter
-
-
If config ’s fenced frame reporting metadata 's value is null, set to null.
-
Otherwise, set to a fenced frame reporter with the following members:
- fenced frame reporting metadata reference
-
a reference to config ’s fenced frame reporting metadata 's value
- automatic beacon data
-
null
-
- exfiltration budget metadata reference
-
-
If config ’s exfiltration budget metadata is null, set to null.
-
Otherwise, set to a exfiltration budget metadata reference :
- origin
-
config ’s exfiltration budget metadata 's value 's origin
- amount to debit reference
-
a reference to config ’s exfiltration budget metadata 's value 's amount to debit
-
- nested configs
-
-
If config ’s nested configs is null, set to null.
-
Otherwise:
-
Let results be a new map .
-
For each nested config of config ’s nested configs 's value :
-
Set nested configs to results .
-
-
- partition nonce
-
a random, unique partition nonce
- embedder shared storage context
-
config ’s embedder shared storage context
Each browsing context has a fenced frame config instance , which is a fenced frame config instance or null, initially null.
This
fenced
frame
config
instance
should
really
exist
on
browsing
context
group
,
however
until
third-party
cookies
are
deprecated
,
this
specification
supports
many
of
the
fencedframe
concepts
on
the
iframe
element.
This
requires
that
for
the
short
term,
a
normal
content
navigable
be
able
to
load
a
fenced
frame
config
,
and
therefore
have
access
to
the
navigation’s
corresponding
fenced
frame
config
instance
.
2.3.4.
The
FencedFrameConfig
interface
One
major
input
to
the
fencedframe
element
is
the
FencedFrameConfig
interface,
which
maps
to
an
internal
fenced
frame
config
struct
.
enum {OpaqueProperty };"opaque" typedef (unsigned long or OpaqueProperty );FencedFrameConfigSize typedef USVString ; [FencedFrameConfigURL Exposed =Window ,Serializable ]interface {FencedFrameConfig readonly attribute FencedFrameConfigSize ?;containerWidth readonly attribute FencedFrameConfigSize ?;containerHeight readonly attribute FencedFrameConfigSize ?;contentWidth readonly attribute FencedFrameConfigSize ?;contentHeight undefined setSharedStorageContext (DOMString ); };contextString
Note:
Note
that
FencedFrameConfig
s
cannot
be
constructed
manually
from
JavaScript.
They
can
only
be
created
by
config-generating
APIs.
However,
some
browsers
support
a
developer-only
flag
which
help
developers
test
the
fencedframe
element
with
arbitrary
URLs
not
produced
by
config-generating
APIs
for
development.
Each
FencedFrameConfig
has:
-
A urn , a urn uuid
-
A sharedStorageContext , a string
-
A containerWidth , a
FencedFrameConfigSizeor null -
A containerHeight , a
FencedFrameConfigSizeor null -
A contentWidth , a
FencedFrameConfigSizeor null -
A contentHeight , a
FencedFrameConfigSizeor null
setSharedStorageContext(
contextString
)
method
steps
are
to
set
this
's
sharedStorageContext
to
contextString
.
FencedFrameConfig
objects
are
serializable
objects
.
Their
serialization
steps
,
given
value
,
serialized
,
and
forStorage
are:
-
If forStorage is true, then throw a
DataCloneErrorDOMException. -
Set serialized .[[Urn]] to value ’s urn .
-
Set serialized .[[SharedStorageContext]] to value ’s sharedStorageContext .
-
Set serialized .[[ContainerWidth]] to value ’s containerWidth .
-
Set serialized .[[ContainerHeight]] to value ’s containerHeight .
-
Set serialized .[[ContentWidth]] to value ’s contentWidth .
-
Set serialized .[[ContentHeight]] to value ’s contentHeight .
-
Initialize value ’s urn to serialized .[[Urn]].
-
Initialize value ’s sharedStorageContext to serialized .[[SharedStorageContext]].
-
Initialize value ’s containerWidth to serialized .[[ContainerWidth]].
-
Initialize value ’s containerHeight to serialized .[[ContainerHeight]].
-
Initialize value ’s contentWidth to serialized .[[ContentWidth]].
-
Initialize value ’s contentHeight to serialized .[[ContentHeight]].
2.4.
The
Fence
interface
Several
APIs
specific
to
fenced
frames
are
defined
on
the
Fence
interface.
enum {FenceReportingDestination ,"buyer" ,"seller" ,"component-seller" ,"direct-seller" , };"shared-storage-select-url" dictionary {FenceEvent required DOMString ;eventType required DOMString ;eventData required sequence <FenceReportingDestination >;destination boolean =once false ; };typedef (FenceEvent or DOMString ); [ReportEventType Exposed =Window ]interface {Fence undefined reportEvent (ReportEventType );event undefined setReportEventDataForAutomaticBeacons (FenceEvent );event sequence <FencedFrameConfig >getNestedConfigs (); };
reportEvent(
event
)
method
steps
are:
-
Let instance be this 's relevant global object 's browsing context 's fenced frame config instance .
-
If instance is null, then return.
-
If the relevant settings object 's origin and instance ’s mapped url 's origin are not same origin , then return.
-
If instance ’s fenced frame reporter is null, then return.
-
If event is a
DOMString, run report a private aggregation event using instance ’s fenced frame reporter with event . -
If event is a
FenceEvent, for each destination of event ’sdestination:-
Run report an event using instance ’s fenced frame reporter with destination , event ’s
eventType, and event ’seventData.
-
setReportEventDataForAutomaticBeacons(
event
)
method
steps
are:
-
If event ’s
eventTypeis not"reserved.top_navigation", return. -
Let instance be this 's relevant global object 's browsing context 's fenced frame config instance .
-
If instance is null, then return.
-
If the relevant settings object 's origin and instance ’s mapped url 's origin are not same origin , then return.
-
If instance ’s fenced frame reporter is null, then return.
-
Set instance ’s fenced frame reporter 's automatic beacon data to a struct with the following items :
- eventData
-
event ’s
eventData - destination
-
event ’s
destination - once
-
event ’s
once
getNestedConfigs()
method
steps
are:
-
Let instance be this 's relevant global object 's browsing context 's fenced frame config instance .
-
If instance is null, then return.
-
If the relevant settings object 's origin and instance ’s mapped url 's origin are not same origin , then return.
-
If instance ’s nested configs is null, then return.
-
Let results be an empty list of
FencedFrameConfigs. -
For each urn → config of instance ’s nested configs :
-
Let newConfig be a new
FencedFrameConfigobject created in this 's relevant realm , with the following:- urn
-
urn
- sharedStorageContext
-
config ’s embedder shared storage context
- containerWidth
-
null if config ’s container size is null, otherwise config ’s container size 's width
- containerHeight
-
null if config ’s container size is null, otherwise config ’s container size 's height
- contentWidth
-
null if config ’s content size is null, the
"opaque"OpaquePropertyif config ’s content size 's visibility is opaque , otherwise config ’s content size 's width - contentHeight
-
null if config ’s content size is null, the
"opaque"OpaquePropertyif config ’s content size 's visibility is opaque , otherwise config ’s content size 's height
-
Append newConfig to results .
-
-
Return results .
2.5. New request destination
The
processing
model
of
a
fencedframe
's
navigation
request
deviates
from
that
of
the
normal
navigation
request
in
enough
ways
to
justify
a
new
request
destination
value.
This
specification
updates
the
request
destination
enumeration
to
include
a
new
entry,
"
fencedframe
".
Perform
the
following
monkeypatches
to
the
[FETCH]
Standard.
Add
"
fencedframe
"
to
the
non-subresource
request
list
and
to
the
navigation
request
list.
Add
"
fencedframe
"
to
the
RequestDestination
enum.
A user agent should set value to the first matching statement, if any, switching on request’s destination :
Add
"
fencedframe
"
to
the
switch
cases
alongside
"
document
",
"
frame
",
and
"
iframe
".
Non-normatively,
update
the
DOM
intro
destination
table
to
illustrate
that
fencedframe
navigation
requests
have
the
following
properties:
-
destination of "
fencedframe" -
initiator ""
-
CSP directive of
fenced-frame-src -
Features as HTML’s
<fencedframe>
2.6. Automatic Reporting
This first introductory paragraph is non-normative.
A
side
effect
of
the
fenced
boundary
model
is
that
ads
will
lose
the
ability
to
know
if
a
click
resulted
in
a
successful
navigation.
This
is
because
the
page
loaded
from
a
top-level
navigation
originating
from
a
fenced
frame
will
not
be
allowed
to
report
to
the
fenced
frame
that
it
loaded
(through
something
like
window.
opener
).
Instead,
we
introduce
a
special
event-level
reporting
type
,
reserved.top_navigation
,
which
automatically
sends
an
event-level
beacon
when
a
fenced
frame
initiates
a
successful
navigation
to
a
top-level
traversable
.
Document
targetDocument
,
and
a
string
eventType
,
run
these
steps:
-
Assert : eventType is "
reserved.top_navigation". -
If targetDocument ’s node navigable 's traversable navigable is not a top-level traversable , abort these steps.
-
If sourceSnapshotParams ’s has transient activation is set to false, abort these steps.
-
Let config be sourceSnapshotParams ’s initiator fenced frame config instance .
-
If config is null, abort these steps.
Note: Since this algorithm is called unconditionally for all navigations, this is used to catch cases where a navigation to a top-level traversable does not originate from a
fencedframe. -
Let beacon data be config ’s fenced frame reporter 's automatic beacon data .
-
IfLet event data be beacon data ’s eventData if beacon data is not null,abort these steps.the empty string otherwise. -
If sourceOrigin is not same origin with config ’s mapped url 's origin , abort these steps.
-
For each destination of
beacon dataconfig ’sdestinationfenced frame reporter 's fenced frame reporting metadata reference 's fenced frame reporting map 's keys :-
RunIf beacon data ’s destinations contains destination , run report an event using config ’s fenced frame reporter with destination , eventType , andbeaconevent data .Otherwise, run report an event using config ’s
eventData .fenced frame reporter with destination , eventType , and the empty string.
-
-
If beacon data ’s once is true, set config ’s fenced frame reporter 's automatic beacon data to null.
-
if failure is false, then attempt to send an automatic beacon given sourceSnapshotParams , entry ’s document state 's initiator origin , document , and "
reserved.top_navigation".
3. HTML Integration
3.1.
Extensions
to
the
Window
interface
partial interface Window { // Collection of fenced frame APIsreadonly attribute Fence ?fence ; };
Each
Window
object
has
an
associated
fence
,
which
is
a
Fence
instance
created
alongside
the
Window
.
fence
getter
steps
are:
-
If this 's browsing context 's fenced frame config instance is not null, then return this 's fence .
-
Return null.
3.2. Modifications to creating browsing contexts
-
If creator is non-null, then:
to instead use the tighter condition:
-
If creator is non-null and embedder is not a
fencedframeelement, then:
Note: This is because we need to ensure that we do not leak creator ’s referrer , origin , creator base url , policy container , across the fenced frame boundary.
Add a substep to step 4 of this algorithm (that was modified above) that reads:
-
Set browsingContext ’s fenced frame config instance to creator ’s browsing context 's fenced frame config instance .
3.3. Policy container inheritance
When
making
a
navigation
request
to
a
local
URL
,
iframe
s
clone
their
policy
container
from
the
navigation
request
's
initiator
Document
.
If
fencedframe
s
were
to
do
the
same
thing,
that
would
allow
information
about
the
initiator’s
policy
container
to
leak
across
a
fenced
frame
boundary.
This
section
patches
policy
container
inheritance
to
close
that
leak.
Rewrite step 3 to read:
-
If responseURL is local , initiatorPolicyContainer is not null, and fenced false, then return a clone of initiatorPolicyContainer .
Note:
We
do
not
need
to
modify
the
case
where
responseURL
is
about:srcdoc
,
because
navigations
to
about:srcdoc
are
not
supported
in
fenced
frames.
-
Let fenced be true if navigable is a fenced navigable , false otherwise.
Note: This ensures fenced is true regardless of whether the initiator
Documentis navigable ’s active document or its unfenced parent .
Rewrite step 23 (now step 24) to read:
-
Let resultPolicyContainer be the result of determining navigation params policy container given response ’s URL , entry ’s document state 's history policy container , sourceSnapshotParams ’s source policy container , null, responsePolicyContainer , and fenced .
Note:
fencedframe
policy
container
inheritance
upon
initial
Document
creation
is
handled
in
the
§ 3.2
Modifications
to
creating
browsing
contexts
section.
3.4. Nested traversables
3.4.1. Introduction
This section is non-normative.
The
[HTML]
Standard
organizes
navigables
into
two
categories:
child
navigables
and
traversable
navigables
(also
known
as
top-level
traversables
).
The
introduction
of
features
like
fenced
frames,
and
to
a
lesser
extent
portals
,
complicates
this
model
by
adding
a
new
type
of
traversable
navigable
that
is
sometimes
like
a
child
navigable
.
Because
these
new
frame
types
are
housed
in
a
separate
browsing
context
group
from
their
embedder,
some
concrete
level
of
isolation
is
expected
and
required;
on
the
other
hand
since
they
are
composed
visually
inside
of
other
browsing
context
groups
,
sometimes
they
need
to
behave
like
the
normal
child
navigables
that
we
see
in
e.g.,
iframe
s.
The complexity here is in deciding when terms like navigable container , navigable parent , and descendant navigables need to cross the traversable navigable / browsing context group boundary, versus when doing so would be unsafe or incorrect. The examples below illustrate this point.
When
a
user
activates
content
inside
of
a
Document
,
ordinarily
the
activation
notification
steps
give
user
activation
to
all
ancestor
navigables
and
all
same
origin
descendant
navigables
.
But
because
a
fencedframe
can
host
sensitive
content
that
needs
to
be
isolated
from
its
embedder,
and
because
user
activation
and
consumption
offer
a
communication
vector
between
these
two
parties,
for
the
purpose
of
user
activation
a
fencedframe
's
fenced
navigable
cannot
not
be
considered
a
descendant
of
its
embedder,
nor
can
its
embedder
be
considered
an
ancestor
of
the
fencedframe
's
fenced
navigable
,
in
the
way
that
the
user
activation
algorithms
currently
use
those
terms.
In
other
words,
we
consider
user
activation
to
be
fenced
,
to
denote
that
it
never
crosses
the
fenced
navigable
boundary;
if
it
were
unfenced,
it
would
behave
as
it
would
with
iframe
s,
allowing
user
activation
to
flow
freely
across
the
frame
boundary.
Unlike
user
activation
,
when
a
fencedframe
's
fenced
navigable
gets
created
or
navigated
,
it
must
inherit
its
embedder
Document
's
active
sandboxing
flag
set
as
is
standard
for
Document
s
in
normal
child
navigables
.
If
we
did
not
do
this,
then
the
fencedframe
element
would
be
a
trivial
sandbox
bypass.
Because
fencedframe
sandbox
flag
inheritance
behaves
similarly
to
how
it
does
in
iframe
elements,
we
consider
sandbox
inheritance
to
be
unfenced
.
To provide the isolation mentioned above, and its conditional relaxation, this specification defines a new kind of parent for traversable navigables called an unfenced parent , which provides a link to its embedder that algorithms can intentionally use when they need to be unfenced , as described above.
Note:
Introducing
a
new
kind
of
parent
(
unfenced
parent
)
is
an
intentional
design
decision.
It
means
that
by
default,
the
fencedframe
boundary
is
private
and
isolated,
since
by
default
nothing
in
the
web
platform
traverses
from
a
fencedframe
's
fenced
navigable
to
its
embedder.
Care
must
be
taken
when
modifying
algorithms
to
make
them
capable
of
traversing
across
the
fencedframe
fenced
navigable
boundary,
and
each
modification
of
this
sort
will
be
evaluated
independently
and
appear
in
this
specification.
The rest of this section provides patches to various [HTML] definitions (and their uses) that deal with collections of related navigables, with the intention of fencing and unfencing various parts of the web platform appropriately.
3.4.2. Traversable navigables
In [HTML] 's Traversable navigables section, add the following:
In addition to the properties of a navigable , a traversable navigable has:
-
An unfenced parent , a navigable or null, initially null.
Note:
The
unfenced
parent
link
is
what
gives
a
fencedframe
's
fenced
navigable
a
link
to
its
embedder,
which
is
used
carefully
for
things
that
need
to
be
"
unfenced
",
like
some
algorithms
in
the
focus
processing
model.
-
If navigable is a child navigable , return navigable ’s parent .
-
Assert : navigable is a fenced navigable .
-
Return navigable ’s unfenced parent .
Note: This algorithm is different from the traversable navigable 's unfenced parent getter in that this algorithm first tries to get the navigable 's normal parent if navigable is a normal child navigable .
-
Let parentNavigable be navigable ’s unfenced parent .
-
Return parentNavigable ’s active document .
3.4.3. Nested traversables
In [HTML] 's Navigables section, add a new subsection titled "Nested traversables" with the following text, definitions, and algorithms.
Similar
to
navigable
containers
and
their
respective
content
navigables
,
other
elements
(so
far,
only
the
fencedframe
element)
present
a
more
isolated
navigable
to
the
user.
These
elements
are
called
fenced
navigable
containers
.
A fenced navigable container has a fenced navigable , which is either a traversable navigable with a non-null unfenced parent , or null. It is initially null.
-
Initialize the navigable traversable given documentState .
-
Set traversable ’s unfenced parent to parent .
-
Let group be a new browsing context group .
Note: There doesn’t seem to be a reason to append group to the user agent’s browsing context group set like create a new browsing context group and document does.
-
Let document be the second return value of creating a new browsing context and document given element node document , element , and group .
-
Let documentState be a new document state , whose document is document .
-
Let traversable be a new traversable navigable .
-
Let parentNavigable be element ’s node navigable .
-
Initialize the nested traversable traversable given documentState and parentNavigable .
-
Set element ’s fenced navigable to traversable .
-
Let initialHistoryEntry be traversable ’s active session history entry .
-
Set initialHistoryEntry ’s step to 0.
-
Append initialHistoryEntry to traversable ’s session history entries .
-
Return traversable .
Note: The create a new nested traversable algorithm creates the first kind of traversable navigable that is not a top-level traversable . This will require removing the note about nested traversables in [HTML] 's Top-level traversables section.
3.4.4. Top-level traversables
The [HTML] Standard currently defines a top-level traversable as a traversable navigable whose parent is null, however this is an insufficient definition that this specification changes. [HTML] mentions that outside of this specification, all traversable navigables are top-level traversables , but "envisions" future specifications that may want to create a kind of traversable that is nested, and achieves the nesting through a non-null parent ; hence the distinction between top-level traversables and traversable navigables relies on the parent null-ness.
The fenced navigable this specification proposes is precisely what [HTML] envisioned when carving out space for the distinction between top-level traversables and traversable navigables , however this specification does not make use of the parent pointer for fenced navigables , for reasons described above (instead they use the unfenced parent pointer). That means by default, both top-level traversables and fenced navigables both have null parents , which renders the distinction meaningless.
To mend the intended distinction between top-level traversables and fenced navigables , patch the following definitions like so:
-
Let navigable be inputNavigable .
-
While :
-
If navigable ’s parent and unfenced parent are both null, then break .
-
Set navigable to navigable ’s parent or unfenced parent , whichever is non-null.
Note: Exactly one of navigable ’s parent or unfenced parent will be non-null here.
-
-
Return navigable .
Note: With these new definitions, a top-level traversable is essentially "unfenced" as described in the § 3.4.1 Introduction .
3.5. Modifications to navigable-traversing algorithms
Further rewrite step 2 of this algorithm to:
-
Extend navigables with document ’s descendant navigables with unfenced set to unfenced .
-
Let navigables be a new list .
-
Let navigableContainers be a list of all shadow-including descendants of document that are navigable containers (or fenced navigable containers , if unfenced is true), in shadow-including tree order .
-
For each navigableContainer of navigableContainers :
-
If navigableContainer ’s content navigable and fenced navigable are both null, then continue .
-
Let descendantNavigable be either navigableContainer ’s content navigable or fenced navigable , whichever is non-null.
-
Extend navigables with descendantNavigable ’s active document 's inclusive descendant navigables with unfenced set to unfenced .
-
-
Return navigables .
3.6. Modifications to the focusing algorithms
The
[HTML]
standard
defines
how
to
handle
focusing
elements
and
Window
s,
both
by
user
gesture
and
through
script-initiated
APIs.
Since
fenced
frames
are
designed
to
prevent
communication
across
a
fenced
frame
boundary,
we
need
to
handle
focusing
carefully.
This
is
because
when
focus
crosses
a
fencedframe
boundary,
contexts
on
both
sides
of
the
boundary
can
detect
that
change,
which
can
be
used
to
open
a
communication
channel
between
a
fencedframe
and
its
embedder.
We do this by not allowing the focusing steps to move script-initiated focus across a fenced frame boundary.
When
a
user
clicks
on
an
element
like
a
button
inside
a
fencedframe
while
another
element
outside
of
the
fencedframe
is
focused
,
the
focusing
steps
will
allow
the
button
to
gain
focus
,
because
this
is
specifically
a
user-initiated
action.
Without
allowing
that,
no
element
inside
of
a
fencedframe
would
never
be
able
gain
focus
.
If
we
were
to
continue
allowing
all
elements
to
be
focused
via
the
focus()
method
as
is
the
status
quo
before
this
specification,
a
fenced
navigable
container
and
its
fenced
navigable
could
use
a
sequence
of
focus()
calls
to
send
arbitrary
data
across
the
fenced
frame
boundary,
which
is
a
privacy
leak.
To
avoid
this,
we
effectively
"fence"
the
focus()
method,
which
sacrifices
some
functionality
for
privacy.
Add a new step after step 3 of the algorithm (that changes new focus target) that reads:
-
If new focus target is a fenced navigable container with non-null fenced navigable , then set new focus target to the fenced navigable 's active document .
Add a new step after the step that defines the new chain variable, that reads:
-
If unfenced is false, new chain contains a
Documentdocument whose node navigable 's traversable navigable is a fenced navigable , and old chain does not also contain document , then return.Note: This is how we bail-out early just before calling the focus update steps , in the case where focus is trying to cross the fence.
Modify the user agent sentence after the algorithm steps in focusing steps to read:
User agents must immediately run the focusing steps for a focusable area or navigable candidate with unfenced set to true whenever the user attempts to move the focus to candidate .
-
Run the focusing steps for the element with unfenced set to true.
-
Fire a
clickevent at the element.
When
a
user
activates
a
click
focusable
focusable
area
,
the
user
agent
must
run
the
focusing
steps
on
the
focusable
area
with
focus
trigger
set
to
"
click
"
and
unfenced
set
to
true.
-
If previouslyFocusedElement is not null, then:
-
Set element ’s previously focused element to null.
-
If focusPreviousElement is true, then run the focusing steps for previouslyFocusedElement with unfenced set to true; the viewport should not be scrolled by doing this step.
-
Note: Although dismissing a popover manually is a user-initiated gesture, the focusing steps will be called with unfenced set to false regardless of whether this was called from user gesture or via a script call.
-
User agents may focus one of those elements in the process, by running the focusing steps for that element, and may change the scrolling position of the document, or perform some other action that brings the element to the user’s attention. If these steps were invoked by user gesture, focusing steps can be called with unfenced set to true. For elements that are form-associated custom elements , user agents should use their face validation anchor instead, for the purposes of these actions.
-
If the focused area of candidate is a fenced navigable container with a non-null fenced navigable , then set candidate to the active document of that fenced navigable container 's fenced navigable .
-
If currentObject is a focusable area , then set currentObject to currentObject ’s DOM anchor 's node document .
Otherwise, if currentObject is a
Documentwhose node navigable 's parent is non-null, then set currentObject to currentObject ’s node navigable 's parent .Otherwise, if currentObject is a
Documentwhose node navigable is a traversable navigable whose unfenced parent is non-null, then set currentObject to currentObject ’s node navigable 's unfenced parent .Otherwise, break .
- If focus target is a fenced navigable container with a non-null fenced navigable
-
Return the fenced navigable container 's fenced navigable 's active document .
Note: This algorithm can unconditionally "jump the fence" boundary because its return value always feeds into an algorithm that does carefully consider the fence boundary.
-
While candidate ’s focused area is either a navigable container with a non-null content navigable or a fenced navigable container with a non-null fenced navigable : set candidate to the active document of either that navigable container 's content navigable or that fenced navigable container 's fenced navigable , whichever is non-null.
-
If candidate is not null, then run the focusing steps for candidate with unfenced set to true and return.
Modify step 9 of the sequential focus navigation algorithm to read:
-
Otherwise, starting point is a focusable area whose node document 's node navigable is a child navigable or fenced navigable . Set starting point to that node navigable 's unfenced parent and return to the step labeled loop .
-
If candidate is a navigable container with a non-null content navigable , then let new candidate be the result of running the sequential navigation search algorithm with candidate ’s content navigable as the first argument, direction as the second, and sequential as the third.
If candidate is a fenced navigable container with a non-null fenced navigable , then let new candidate be the result of running the sequential navigation search algorithm with candidate ’s fenced navigable as the first argument, direction as the second, and sequential as the third.
If new candidate is null, then let starting point be candidate , and return to the top of this algorithm. Otherwise, let candidate be new candidate .
Tests
3.7. Navigation
This
section
describes
how
the
fencedframe
element
interacts
with
the
ever-complicated
process
of
navigation,
which
includes
integration
with
various
headers,
isolation
mechanisms,
and
policies.
3.7.1.
The
`
Supports-Loading-Mode
`
HTTP
response
header
This
section
is
intended
to
monkeypatch
the
[HTML]
Standard,
however
since
the
`
Supports-Loading-Mode
`
header
has
not
been
merged
into
[HTML]
yet,
and
instead
lives
in
the
[Prerendering-Revamped]
specification,
this
section
effectively
monkeypatches
that
monkeypatch
specification.
Add
the
new
token
below
to
the
list
of
valid
tokens
for
the
`
Supports-Loading-Mode
`
response
header:
The
`
fenced-frame
`
token
indicates
that
the
response
can
be
used
to
create
a
Document
inside
of
a
fenced
navigable
.
Without
this
explicit
opt-in,
all
navigations
inside
of
a
fenced
navigable
will
fail,
as
outlined
in
§ 3.7
Navigation
.
-
Otherwise, if all of the following conditions are true:
-
navigationParams ’s navigable 's traversable navigable is a fenced navigable ;
-
navigationParams ’s response 's URL 's scheme is "
https"; and -
the result of getting the supported loading modes for navigationParams ’s response does not contain `
fenced-frame`
then set failure to true.
-
3.7.2. COOP, COEP, and cross-origin isolation
Outside
of
this
specification,
the
`
Cross-Origin-Opener-Policy
`
header
only
applies
to
top-level
traversables
instead
of
all
navigables
,
and
this
specification
continues
this
intention
insofar
as
this
header
does
not
have
an
impact
on
fenced
navigables
,
nor
is
it
inherited
from
its
embedder.
Consequently,
the
browsing
context
group
hosted
inside
of
a
fenced
traversable
navigable
will
always
have
its
cross-origin
isolation
mode
set
to
"
none
".
Nevertheless, a fenced navigable respects its unfenced parent 's embedder policy , which is accomplished below:
-
navigable ’s container document
with:
-
navigable ’s unfenced container document
Note:
This
causes
navigations
inside
of
a
fencedframe
to
fail
if
they
are
not
served
with
a
suitable
`
Cross-Origin-Embedder-Policy
`
header,
just
as
iframe
s
behave.
Determine if we need to fence or unfence the queue a cross-origin embedder policy inheritance violation algorithm, as leaving it unfenced may cause a privacy leak.
-
If response is not a network error , navigable is a child navigable or fenced navigable , and the result of performing a cross-origin resource policy check with navigable ’s unfenced container document 's origin , navigable ’s unfenced container document 's relevant settings object , request ’s destination , response , and true is blocked , then set response to a network error and break .
Note: Here we’re running the cross-origin resource policy check against the unfenced parent navigable rather than navigable itself. This is because we care about the same-originness of the embedded content against the embedder’s context (ignoring the "fence"), not the navigation source.
Determine if we need to fence or unfence the queue a cross-origin embedder policy CORP violation report algorithm, as leaving it unfenced may cause a privacy leak.
Tests
3.7.3. Actual navigation changes
- initiator fenced frame config instance
-
a fenced frame config instance or null, initially null.
- target fenced frame config
-
a fenced frame config or null, initially null.
Note:
The
initiator
fenced
frame
config
instance
is
the
fenced
frame
config
instance
that’s
loaded
into
a
navigation
initiator’s
browsing
context
,
if
any
exists.
It
is
used
by
the
attempt
to
send
an
automatic
beacon
algorithm
to
retrieve
the
automatic
beacon
data
to
be
sent
out
if
the
fencedframe
-initiated
navigation
succeeds.
The
target
fenced
frame
config
on
the
other
hand,
is
the
non-
instantiated
fenced
frame
config
that
will
be
loaded
into
a
a
fencedframe
element
for
navigations
targeting
fenced
frames.
These
fields
do
not
interact
together
in
any
meaningful
way.
- initiator fenced frame config instance
-
sourceDocument ’s browsing context 's fenced frame config instance
Modify step 7 of [HTML] 's navigate algorithm to include the following condition:
-
navigable is a fenced navigable ;
Note: This ensures that all navigations inside of a
fencedframeare made with the "replace" mode, regardless of the initiator.
Tests
Modify step 8 of the same algorithm to include the following condition:
-
sourceDocument ’s node navigable is not a fenced navigable container while at the same time navigable is a fenced navigable .
Note: This ensures that embedder-initiated navigations can never trigger a fragment navigation inside of a
fencedframe.
Insert these steps immediately after step 20, the step that goes in parallel , so that what follows are the first steps that run in parallel in the patched algorithm:
-
If url is a urn uuid and navigable is a fenced navigable :
-
Let config be the result of finding a config in sourceDocument ’s node navigable 's traversable navigable 's fenced frame config mapping .
Note: This might "wait" for an arbitrary period of time for the config associated with the urn uuid url to be "finalized" in the fenced frame config mapping . This is why this step runs in parallel . This navigation will be canceled by any subsequent embedder-initiated navigations, should they occur, by the usual mechanism that tracks the ongoing navigation .
-
Set config ’s embedder shared storage context to sharedStorageContext .
-
Set sourceSnapshotParams ’s target fenced frame config to config .
-
Assert config ’s mapped url 's value is a URL whose scheme is "
https". -
Set url to config ’s mapped url 's value .
-
Rewrite the step starting with "Let unloadPromptCanceled be the result of" to:
-
Let unloadPromptCanceled be false if navigable is a fenced navigable , or the result of checking if unloading is user-canceled for navigable ’s active document 's inclusive descendant navigables otherwise.
The below patches make use of the previously-assigned target fenced frame config , instantiating it in preparation for use when the navigation is finalized.
- fenced frame config instance
-
A fenced frame config instance or null, initially null.
Note: This is only set for embedder-initiated
fencedframenavigations, and if a newDocumentis created as a result of such a navigation, this member is transferred to the new fenced navigable 's active browsing context 's fenced frame config instance member.
- fenced frame config instance
-
If sourceSnapshotParams ’s target fenced frame config is null, then null; otherwise, the result of instantiating sourceSnapshotParams ’s target fenced frame config .
Finally, the below patches make use of the navigation params 's fenced frame config instance , and handle the assignment of a browsing context 's fenced frame config instance that is initiated by a navigation.
Note:
A
browsing
context
's
fenced
frame
config
instance
is
assigned
in
two
different
ways:
(1)
during
embedder-initiated
fencedframe
navigation,
as
described
by
the
rest
of
this
section,
and
(2)
inherited
during
initial
Document
creation
for
Document
s
in
child
navigables
whose
traversable
navigable
is
a
fenced
navigable
,
as
handled
in
the
§ 3.2
Modifications
to
creating
browsing
contexts
section.
For
any
successful
navigation
inside
of
a
fencedframe
,
regardless
of
whether
it
was
initiated
by
content
in
the
fencedframe
or
its
embedder,
exactly
one
of
two
things
will
happen:
-
Embedder-initiated navigations : The navigation params 's fenced frame config instance will be unconditionally assigned to the
fencedframe's fenced navigable container 's fenced navigable 's active browsing context 's fenced frame config instance . -
Inner-content-initiated navigations : The fenced frame config instance referenced in the immediately-preceding point persists through this kind of cross-
Documentnavigation.
-
If navigationParams ’s fenced frame config instance is not null:
-
Assert : browsingContext does not equal navigationParams ’s navigable 's active browsing context .
Note: This is because embedder-initiated navigations (indicated by navigationParams ’s fenced frame config instance being non-null) always cause a § 3.7.4 Browsing context group swap .
-
Set browsingContext ’s fenced frame config instance to navigationParams ’s fenced frame config instance .
-
TODO: Call the on navigate callback at the appropriate time.
3.7.4. Browsing context group swap
When
the
embedder
of
a
fencedframe
initiates
navigations
inside
the
frame,
we
must
perform
a
browsing
context
group
swap
to
entirely
reset
the
context
inside
the
frame,
to
ensure
nothing
is
left
over
to
be
leaked
to
the
next
Document
.
-
If all of the following conditions are true:
-
navigable is a fenced navigable ;
-
sourceSnapshotParams ’s fetch client is not navigable ’s active document 's relevant settings object ;
-
navigationParams is non-null
then set navigationParams ’s COOP enforcement result 's needs a browsing context group switch boolean to true.
This indeed works, but we should consider using a separate mechanism to carry this out, instead of piggybacking off of the COOP mechanism which was designed without fenced frames in mind, and could evolve in ways that give this specification unwanted side-effects.
-
3.8. Page visibility
The Page visibility section of [HTML] is modified such that the first step of the algorithm that runs when a user-agent changes a traversable navigable 's system visibility state calls the inclusive descendant navigables algorithm with unfenced set to true.
4. Interactions with other specifications
Due
to
the
necessarily
cross-cutting
nature
of
the
fencedframe
element
and
its
interactions
with
core
concepts
like
navigable
and
browsing
context
group
,
there
are
a
number
of
specifications
that
rely
on
terms
whose
usages
must
be
re-evaluated
in
light
of
this
specification;
this
section
houses
the
various
changes
that
we
propose
to
other
specifications.
4.1. Prerendering
The Prerendering Revamped specification defines navigable 's loading mode and the values it can take on. Our specification adds another value for fenced frames:
-
"
fencedframe" -
This navigable is displaying a
fencedframe's content
Specify the behavior that leads to the following:
4.2. Content Security Policy
This introductory section is non-normative .
Content
Security
Policy
[CSP]
can
ordinarily
be
used
by
web
content
associated
with
a
Document
that
hosts
a
navigable
container
to
limit
the
source
of
navigations
in
a
child
navigable
.
In
order
to
prevent
[CSP]
from
being
used
a
communication
side-channel
exposing
the
URL
of
navigations
inside
a
fencedframe
to
the
site
operating
its
embedder,
the
only
source
expressions
that
can
influence
a
fencedframe
navigation
are:
-
The scheme-source "
https:" -
The host-source "
https://*:*" -
The string "
*"
See our CSP explainer that describes this.
4.2.1. Algorithms
-
If request ’s destination is "
fencedframe", and this directive’s value does not contain either "https:", "https://*:*", or "*", return "Blocked".
-
If request destination is "
fencedframe", and this directive’s value does not contain either "https:", "https://*:*", or "*", return "Blocked".
Next, we modify the behavior of the [CSPEE] specification. If the embedding frame specifies a required CSP , fenced frames will not load. This is done to prevent arbitrary data flow from the embedder to the fenced frame.
-
If context ’s required csp is not
null, and request destination is "fencedframe", return "Blocked".
4.2.2. New fenced-frame-src [CSP] directive
Since
fencedframe
is
a
different
element
than
iframe
,
using
the
frame-src
directive
wouldn’t
give
web
sites
enough
control
over
their
CSP
rules.
Introduce
a
new
[CSP]
directive
:
fenced-frame-src
.
The
monkey-patched
specification
is
printed
below:
fencedframe
's
fenced
navigable
.
The
syntax
for
the
directive’s
name
and
value
is
described
by
the
following
ABNF:
directive-name = "fenced-frame-src" directive-value = serialized-source-list
Content-Security-Policy: fenced-frame-src https://example.com/
Fetches
for
the
following
code
will
return
a
network
error
,
as
the
URL
provided
does
not
match
fenced-frame-src
’s
source
list
:
< fencedframe src = "https://example.org/" > </ fencedframe >
The Pre-request check and Post-request check will be the same as the frame-src ’s check.
Content-Security-Policy: connect-src 'self'; ... worker-src 'self'
It will now say:
Content-Security-Policy: connect-src 'self'; ... fenced-frame-src 'self'; ... worker-src 'self'
-
"
fenced-frame-src" -
-
Return
<< "fenced-frame-src", "frame-src", "child-src", "default-src" >>.
-
-
"
fencedframe" -
-
Return
fenced-frame-src.
-
Tests
- ancestor-throttle.https.html (live test) (source)
- csp-allowed.https.html (live test) (source)
- csp-blocked.https.html (live test) (source)
- csp-fenced-frame-src-allowed.https.html (live test) (source)
- csp-fenced-frame-src-blocked.https.html (live test) (source)
- csp-frame-src-allowed.https.html (live test) (source)
- csp-frame-src-blocked.https.html (live test) (source)
- csp-transparent-url.https.html (live test) (source)
- csp.https.html (live test) (source)
- cspee.https.html (live test) (source)
- embedder-csp-not-propagate.https.html (live test) (source)
4.3. Permissions Policies
This introductory sub-section is non-normative.
The
policy-controlled
features
available
to
Document
s
inside
of
a
fencedframe
are
determined
exclusively
by
the
fenced
frame
config
that
the
fencedframe
navigates
to.
Specifically,
the
fenced
frame
config
's
effective
enabled
permissions
defines
the
exclusive
list
of
policy-controlled
features
that
will
be
enabled
in
the
Document
(all
others
will
be
disabled).
During
navigation,
the
fenced
frame
config
instantiates
a
fenced
frame
config
instance
that
is
stored
on
the
browsing
context
in
the
fenced
navigable
.
This
browsing
context’s
fenced
frame
config
instance
's
effective
enabled
permissions
is
consulted
during
navigation
.
A
fencedframe
navigation
can
only
succeed
if
the
permissions
policy
for
the
navigation’s
resulting
Document
has
an
inherited
policy
such
that
the
inherited
policy
value
is
"
Enabled
"
for
each
feature
in
the
effective
enabled
permissions
.
Otherwise
the
environment
the
fencedframe
is
embedded
in
is
deemed
unsuitable
for
the
fenced
frame
config
,
and
the
navigation
is
blocked.
At
the
same
time,
to
make
sure
that
a
fencedframe
's
embedder
does
not
directly
influence
content
in
the
frame
based
on
that
navigation’s
origin
(since
the
origin
is
derived
from
cross-site
data),
this
specification
modifies
various
[PERMISSIONS-POLICY]
algorithms
such
that
a
fencedframe
Document
's
inherited
policy
is
computed
without
consideration
of
whether
its
origin
is
same
origin
with
its
embedder’s.
Therefore
a
feature
can
only
be
enabled
inside
of
a
fencedframe
if
its
embedder
explicitly
delegates
it
via
the
special
value
*
allowlist
.
Considering all of the above, we get the following interesting implications:
-
If a feature that exists in the effective enabled permissions has a default allowlist of the special value * , and no `
Permissions-Policy` header is served on thefencedframeembedder, and theallowattribute is empty, the navigation inside thefencedframewill succeed, and the resultingDocumentwill be allowed to use the feature (i.e., it will be enabled). -
If a feature that exists in the effective enabled permissions has a default allowlist of
'self', and no `Permissions-Policy` header is served on thefencedframeembedder, and theallowattribute is empty, the navigation inside thefencedframewill be blocked.Note: This is because ordinarily this feature would only be enabled if the subframe’s
Documentwas same origin with its embedder, a check this specification avoids for fenced frames, since thefencedframesDocument's origin is derived from cross-site data. Therefore, we simply "fail close". -
If a feature that exists in the effective enabled permissions has a default allowlist of
'self', and thefencedframe'sallowattribute contains the feature but no allowlist , the rules described in Theallowattribute section , the default allowlist for the feature will be'src'which is meant to represent the embedder-supplied navigation URL , for which there is none when navigating afencedframe, as the navigation URL is determined by the fenced frame config . The navigation will be blocked. -
If a feature that exists in the effective enabled permissions has a default allowlist of
'self'but either the `Permissions-Policy` header served on thefencedframe's embedder OR theallowattribute sets that feature 's allowlist to the special value * , then the navigation inside thefencedframewill succeed, and the resultingDocumentis allowed to use the feature . -
If a navigation inside a
fencedframewould otherwise succeed, but the response on the navigation inside thefencedframeis served with a `Permissions-Policy` header that sets the allowlist to "none" or an otherwise incompatible origin for a feature in the effective enabled permissions , the navigation still succeeds, but theDocumentin thefencedframeis not allowed to use the feature.Note: This is OK because it is the
fencedframe's content itself that is making the decision to disable a particular feature, not its embedder environment.
The patches in the below section "fence" the appropriate [PERMISSIONS-POLICY] and [HTML] algorithms to achieve the outcomes described in the above explanatory content.
4.3.1. Algorithm patches
allow
attribute
of
the
iframe
element
section
to
"The
allow
attribute
of
the
iframe
and
fencedframe
element",
and
rewrite
the
section
to
read:
iframe
and
fencedframe
elements
have
an
respective
allow
attributes
(
iframe
:
allow
;
fencedframe
:
allow
),
which
contain
an
ASCII-serialized
policy
directive
.
The
allowlist
for
the
features
named
in
the
attribute
may
be
empty;
in
that
case,
the
default
value
for
the
allowlist
is
"
src
",
which
represents
the
origin
of
the
URL
in
the
iframe’s
src
attribute,
or
the
fencedframe’s
fenced
frame
config
.
When
not
empty,
the
iframe
's
allow
or
fencedframe
's
allow
attribute
will
result
in
adding
an
allowlist
for
each
supported
feature
to
the
iframe
or
fencedframe
's
container
policy
,
when
it
is
constructed.
Given null or an element ( container ), an origin ( origin ), and an optional boolean fenced that defaults to false, this algorithm returns a new Permissions Policy.
Rewrite step 1 to read:
-
Assert : if not null, container is either a navigable container or a fenced navigable container .
Rewrite step 3 to read:
-
For each feature supported :
-
Let isInherited be the result of running Define an inherited policy for feature in container at origin on feature , container , origin , and fenced .
-
Set inherited policy [ feature ] to isInherited .
-
Given null, a navigable container -or- fenced navigable container ( container ), an origin ( origin ), and a response ( response ), this algorithm returns a new permissions policy .
Add a step before step 1 that reads:
-
Let fenced be true if container is a fenced navigable container , and false otherwise.
Modify what is now step 2 of the algorithm to read:
-
Let policy be the result of running Create a Permissions Policy for a navigable given container , origin , and fenced .
-
Otherwise, if the result of should navigation response to navigation request be blocked by Permissions Policy? given navigationParams is "
Blocked", then set failure to true.
Note:
If
this
algorithm
returns
"
Blocked
",
the
pre-existing
Document
in
the
fencedframe
does
not
stick
around;
an
error
page
will
be
loaded.
Given
a
navigation
params
(
navigationParams
),
this
algorithm
returns
"
Blocked
"
or
"
Allowed
":
-
Let navigable be navigationParams ’s navigable .
-
If navigable is not a fenced navigable , then return "
Allowed". -
Let origin be navigationParams ’s origin .
-
Let effective permissions be the navigable ’s active browsing context 's fenced frame config instance 's effective enabled permissions .
Per work omitted in pull request #84 , the config instance has not yet been assigned to the browsing context. We should consider storing the instance inside navigationParams and reference it from here instead.
-
Let permissions policy be the result of creating a permissions policy given navigable ’s fenced navigable container , origin , and fenced set to true.
Note: This is identical to the permissions policy that will be created when the navigation constructs the ultimate
Documentfor this pending navigation. We create it now and run tests on it since this is the appropriate time to determine if a navigation will fail, and then throw it away. If the navigation succeeds, it will be recreated identically and unconditionally installed on theDocument. -
Let inherited policy be permissions policy ’s inherited policy .
-
For each effective permission of effective permissions :
-
If inherited policy [ effective permission ] is "Disabled", return "
Blocked".
-
-
Return "
Allowed."
Given a feature ( feature ), null or a navigable container ( container ), an origin for a document in that container ( origin ), and an optional boolean fenced that defaults to false, this algorithm returns the inherited policy for that feature.
Rewrite step 3 to read:
-
If the result of executing Is feature enabled in document for origin? on feature , container ’s node document , origin , and fenced is "Disabled", return "Disabled".
Note:
We
don’t
have
to
rewrite
step
2,
which
also
delegates
to
the
same
algorithm,
to
pass
in
the
fenced
boolean
because
step
2
has
to
do
with
checking
to
see
if
feature
is
enabled
container
’s
node
document
,
not
the
Document
hosted
inside
container
.
Rewrite step 7 to read:
-
If fenced is false, feature ’s default allowlist is
'self', and origin is same origin with container ’s node document 's origin, return"Enabled".
Given
a
feature
(
feature
),
a
Document
object
(
document
),
an
origin
(
origin
),
and
an
optional
boolean
fenced
that
defaults
to
false,
this
algorithm
returns
"
Disabled
"
if
feature
should
be
considered
disabled,
and
"
Enabled
"
otherwise.
Rewrite step 3 to read:
-
If feature is present in policy ’s declared policy ,
-
If fenced is false, and the allowlist for feature in policy ’s declared policy matches origin , then return "
Enabled". -
Otherwise, if fenced is true, and the allowlist for feature in policy ’s declared policy is the special value * , then return "
Enabled". -
Otherwise, return "
Disabled".
-
Rewrite step 5 to read:
-
If fenced is false, feature ’s default allowlist is
'self', and origin is same origin with document ’s origin, return "Enabled".
Tests
- default-enabled-features-allow-all.https.html (live test) (source)
- default-enabled-features-allow-none.https.html (live test) (source)
- default-enabled-features-allow-self.https.html (live test) (source)
- default-enabled-features-attribute-allow.https.html (live test) (source)
- default-enabled-features-attribute-change.https.html (live test) (source)
- default-enabled-features-attribute-disallow.https.html (live test) (source)
- default-enabled-features-attribution-disabled.https.html (live test) (source)
- default-enabled-features-subframe.https.html (live test) (source)
- default-enabled-features-unset.https.html (live test) (source)
- permission-api-denied-non-standard.https.html (live test) (source)
- permission-api-denied.https.html (live test) (source)
- permission-geolocation.https.html (live test) (source)
- permission-notification.https.html (live test) (source)
4.4. CSSOM View
The
[CSSOM-VIEW]
specification
defines
the
scrollIntoView()
method
that
calls
the
scroll
a
target
into
view
algorithm.
This
will
not
only
scroll
the
Element
or
viewport
to
make
the
target
visible,
but
will
also
scroll
ancestor
s
if
necessary
to
make
the
target
visible,
essentially
causing
the
scroll
to
"bubble
up".
This
means
that
scrollIntoView()
performed
in
a
child
navigable
or
fenced
navigable
can
be
observed
by
its
embedder,
allowing
for
collusion
across
a
fenced
frame
boundary.
This
section
patches
the
scroll
a
target
into
view
algorithm
to
prevent
that
collusion
at
the
expense
of
some
utility.
-
If scrolling box ’s associated
Element's associatedDocument's node navigable 's traversable navigable is a fenced navigable , or if scrolling box ’s associated viewport 's associatedDocument's node navigable 's traversable navigable is a fenced navigable , then let this be the last instance of this algorithm that stops any further recursive instances that would otherwise follow.
Note: This allows scrolling to "bubble up" to a fenced frame boundary, but not cross it.
5. Security & Privacy Considerations
This material is being upstreamed from our explainer into this specification, and in the meantime you can consult the following resources: