Fenced frames
Securely embed content onto a page without sharing cross-site data.
Implementation status
This document outlines a proposal for a new HTML element: <fencedframe>
.
- The Fenced Frames proposal is now in experimentation.
- Experiment with fenced frames in the Privacy Sandbox unified origin trial from M102 to M107. Learn how to set up the origin trial and join us for a feedback/discussion.
- This feature is available behind a Chrome flag.
- Chrome Platform Status
Proposal | Status |
---|---|
Web API changes for urn to config Explainer | Available in Chrome for origin trial in Q1 2023 |
Add size to API for K-anon check for URLs and frame size Github Issue | Expected in Chrome for origin trial in Q1 2023 |
FLEDGE Fenced Frames support for event-level reports with Attribution Reporting Github Issue | Expected in Chrome for origin trial in Q1 2023 |
FLEDGE, Fenced Frames, and Private Aggregation API support urn-iframes and reportEvent Github Issue | Expected in Chrome for origin trial in Q1 2023 |
FLEDGE component ads reporting Github Issue | Expected in Chrome for origin trial in Q1 2023 |
Deprecate src attribute for the config attributeGithub Issue | Expected in Chrome for origin trial in Q2 2023 |
Why do we need fenced frames?
A fenced frame (<fencedframe>
) is a proposed HTML element for embedded content, similar to an iframe. Unlike iframes, a fenced frame restricts communication with its embedding context to allow the frame access to cross-site data without sharing it with the embedding context. Some Privacy Sandbox APIs may require select documents to render within a fenced frame.
Similarly, any first-party data in the embedding context cannot be shared with the fenced frame.
<fencedframe src="https://3rd.party.example"></fencedframe>
For example, let's say news.example
(the embedding context) embeds an ad from shoes.example
in a fenced frame. news.example
cannot exfiltrate data from the shoes.example
ad, and shoes.example
cannot learn first-party data from news.example
.
Strengthen cross-site privacy with storage partitioning
While browsing the web, you've probably looked at products on one site, and then you've seen them appear again in an ad on a completely different site.
Today, this advertising technique is achieved primarily through tracking technology that uses third-party cookies to share information across sites. This is technology which Chrome has committed to phase out and replace with more privacy-preserving variants.
Chrome is working on storage partitioning, which separates browser storage per-site. Currently, if an iframe from shoes.example
is embedded on news.example
, and that iframe stores a value into storage, then that value can be read from the shoes.example
site. When storage has been partitioned, cross-site iframes will no longer share storage, therefore shoes.example
will not be able to access information stored by the iframe. If the iframe is served from *.shoes.example
and embedded on *.shoes.example
, browser storage will be shared as these are considered same-site.
Storage partitioning will be applied to standard storage APIs including LocalStorage, IndexedDB, and cookies. In a partitioned world, information leakage across first-party storage will be significantly reduced.
Work with cross-site data
Fenced frames is a Privacy Sandbox proposal which suggests top-level sites should partition data. Many Privacy Sandbox proposals aim to satisfy cross-site use cases without third-party cookies or other tracking mechanisms. For example:
- FLEDGE allows for interest-based ad serving in a privacy-preserving manner.
- Shared Storage allows access to unpartitioned cross-site data in a secure environment.
Let's consider how fenced frames could work with the FLEDGE proposal. With FLEDGE, a user's interests are registered on an advertiser's site in interest groups, along with ads that may be of interest to the user. Then, on a separate site (known as a "publisher"), the ads registered in relevant interest groups are auctioned and the winning ad is displayed in a fenced frame.
If the publisher displays the winning ad in an iframe and the script can read the iframe's src
attribute, the publisher can infer information about the visitor's interests from that ad's URL. This is not privacy-preserving.
With a fenced frame, the publisher could display an ad which matches visitor interests, but the src
and interest group will be known only to the advertiser in the frame. The publisher could not access this information.
How do fenced frames work?
A fenced frame will be created from the winner of the FLEDGE API ad auction. The information retrieved from FLEDGE API isn't the URL of the ads itself, but will be an opaque source.
An opaque source is represented by a Uniform Resource Name (URN) for UUIDs. So, instead of http://example.com
(a URL), an opaque source is represented as urn:uuid:c36973b5-e5d9-de59-e4c4-364f137b3c7a
. URN schemes are persistent, location-independent identifiers, which means they cannot be used to locate a resource (such as an ad creative).
Opaque sources allow your site to display ads on a site without revealing the ad source URL to the site owner.
It's not enough to just be able to display ads. If the ad can postMessage
to the publisher's site, like in an iframe, it may leak the content of the displayed ad. So unlike iframes, fenced frames don't allow usage of the postMessage to communicate with the top-level site.
Fenced frames will be isolated from the publisher in other ways. For instance the publisher won't have access to the DOM inside of a fenced frame, and the fenced frame cannot access the publisher's DOM. Further, attributes such as name
—which can be set to any value to and observed by the publisher—aren't available in fenced frames.
Fenced frames behave like a top-level browsing context (such as a browser tab). Although a fenced frame in certain modes (such as opaque-ads
) can contain cross-site data (such as a FLEDGE interest group), the frame cannot access unpartitioned storage or cookies. An opaque-ads
fenced frame can access a unique, nonce-based cookie and storage partition.
The characteristics of fenced frames are further detailed in the explainer.
How do fenced frames compare to iframes?
Now that you know what fenced frames will and won't do, it's useful to compare to existing iframe features.
Feature | iframe | fencedframe |
---|---|---|
Embed content | Yes | Yes |
Embedded content can access embedding context DOM | Yes | No |
Embedding context can access embedded content DOM | Yes | No |
Observable attributes, such as name | Yes | No |
URLs (http://example.com ) | Yes | Yes (mode-dependent) |
Browser-managed opaque source (urn:uuid ) | No | Yes |
Access to cross-site data | No | Yes (mode-dependent) |
Fenced frames support fewer external communication options to preserve privacy.
Will fenced frames replace iframes?
Ultimately, fenced frames won't replace iframes and you won't have to use them. Fenced frames are proposed for a more private frame for usage when data from different top-level partitions needs to be displayed on the same page.
Same-site iframes (sometimes known as friendly iframes) are considered trusted content.
Use fenced frames
Fenced frames will work in combination with other Privacy Sandbox proposals to display documents from different storage partitions within a single page. Potential APIs are currently in discussion.
Current candidates for this combination include:
- From the TURTLEDOVE API family (which is the basis for FLEDGE), fenced frames could work with Conversion Lift Measurement using Shared Storage.
- Another option is to allow fenced frames to be read-only or access unpartitioned storage.
For more details, refer to the Fenced Frames explainer.
Examples
Embedded content inside the <fencedframe>
will be described by the src
attribute.
<fencedframe src="demo_fenced_frame.html"></fencedframe>
Browsers may generate an opaque URL for the fenced frame src
, as requested by certain use case APIs. For example, if a FLEDGE ad auction is run, the browser can generate an urn:uuid
which maps back to the URL for the winning ad creative. That urn:uuid
could then be used in a fenced frame to display the winning ad.
<fencedframe src="urn:uuid:c36973b5-e5d9-de59-e4c4-364f137b3c7a" mode="opaque-ads" ></fencedframe>
Remember, a fenced frame can't use postMessage
to communicate with its parent element. However, a fenced frame can use postMessage
with iframes that are children of the fenced frame, because fenced frames behave like top-level browsing contexts.
Browsers will set Sec-Fetch-Dest: fencedframe
for requests made from fenced frames and iframes that are embedded within a fenced frame.
Sec-Fetch-Dest: fencedframe
Server opt-in
The server must set the Supports-Loading-Mode: fenced-frame
response header for a document to be loaded in a fenced frame. The header must be present for any iframes inside of a fenced frame, as well.
Supports-Loading-Mode: fenced-frame
Try fenced frames
Use Chrome flags to enable the Fenced Frame API at chrome://flags/#enable-fenced-frames
.
There are multiple choices in the dialog. We strongly recommend you select Enable, which allows Chrome to automatically update to new architecture as it becomes available.
The other options, Enabled with ShadowDOM and Enabled with multiple page architecture, offer different implementation strategies which are only relevant to browser engineers. Today, Enable works in the same way as Enabled with ShadowDOM. In the future, Enable will map to Enable with multiple page architecture.
Feature detection
To determine if fenced frames are defined:
if (window.HTMLFencedFrameElement) {
// The fenced frame element is defined
}
Browser support
The <fencedframe>
element is still in experimental mode, so it is currently supported from Chrome 97 onwards. At this time, it's not supported by other browsers.
Engage and share feedback
The Fenced Frame proposal is under active discussion and subject to change in the future. If you try this API and have feedback, we'd love to hear it.
- GitHub: Read the proposal, raise questions, and follow discussion.
- Developer support: Ask questions and join discussions on the Privacy Sandbox Developer Support repo.