Skip to content

Commit

Permalink
Update explainer to talk about configs, rather than urn:uuids and mod…
Browse files Browse the repository at this point in the history
…es (#56)
  • Loading branch information
gtanzer committed Feb 23, 2023
1 parent 9de4dd3 commit f14ad02
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 154 deletions.
23 changes: 9 additions & 14 deletions explainer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ The privacy threat addressed is:

**The ability to correlate the user’s identity/information on the embedding site with that on the embedded site.**

The different use cases and their privacy model are discussed as the different fenced frame modes [here](https://github.com/shivanigithub/fenced-frame/blob/master/explainer/modes.md).
The different use cases and their privacy models are discussed [here](https://github.com/shivanigithub/fenced-frame/blob/master/explainer/use_cases.md).

## Design

Expand All @@ -64,7 +64,7 @@ The idea is that the fenced frame should not have access to both of the followin
* Accessible via an API (e.g., Turtledove) or via access to unpartitioned storage


A primary use case for a fenced frame is to have read-only access to some other partition’s storage, for example, in Turtledove, it is the interest-based ad to be loaded which was added while visiting another site. The URL of the ad is sufficient to give away the interest group that the user belongs to, to the embedding site. Therefore the URL for the ad creative is an opaque url (details [here](https://github.com/shivanigithub/fenced-frame/blob/master/explainer/opaque_src.md)) — which can be used for rendering, but cannot be inspected directly.
A primary use case for fenced frames is to load content that depends on values in another partition’s storage. For example, in Turtledove, we pick an ad based on the user's interest groups (which are joined while browsing other sites) and load it in a fenced frame. The URL of the ad reflects the user's interest group memberships, which is a form of cross-site data, therefore we store the URL for the ad creative _opaquely_ in a fenced frame config (details [here](https://github.com/shivanigithub/fenced-frame/blob/master/explainer/fenced_frame_config.md)). The embedder can use this object to load the ad resulting from the Turtledove auction, but can't inspect it to determine _which_ ad won.

We expect some leakage of information to be possible via network timing attacks. The side channel and some mitigations are described [here](https://github.com/shivanigithub/fenced-frame/blob/master/explainer/network_side_channel.md).

Expand All @@ -85,15 +85,10 @@ Since fenced frames are embedded frames, they also behave like iframes in many w


```
<fencedframe src="demo_fenced_frame.html"></fencedframe>
const fencedframe = document.createElement('fencedframe');
fencedframe.config = new FencedFrameConfig('demo_fenced_frame.html');
```







* Browser lets the server know via a new [`sec-fetch-dest`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Dest) header value `fencedframe` to let it know that a request is from a fenced frame tree.
* The server needs to opt-in to be loaded in a fenced frame or in an iframe embedded in a fenced frame tree. Without an opt-in, the document cannot be loaded. For opt-in, we use the [supports-loading-mode](https://github.com/jeremyroman/alternate-loading-modes/blob/main/opt-in.md#declaration) header with a new value of `fenced-frame`.

Expand Down Expand Up @@ -135,13 +130,13 @@ This discussion assumes that third-party cookies, like all other third party sto

All fenced frame related functions will live in its own class, in the same way that iframe-related funcionality lives in HTMLIFrameElement.

#### Opaque-Ads Can Load API
#### Can Load API

There are various reasons a fenced frame embedded as an opaque ad could refuse to load in a page. For example, if the page is not in a secure context, or if CSPEE is specified in the embedding frame, the fenced frame will refuse to load. This is a lot for a developer to keep track of.
There are various reasons a fenced frame config with an opaque url could refuse to load in a page. For example, if the page is not in a secure context, or if CSPEE is specified in the embedding frame, the fenced frame config will refuse to load. This is a lot for a developer to keep track of.

If the process of getting an ad in the page is complex or expensive, there needs to be a way to ensure that the resulting ad will actually end up in the page before the expensive process begins.

A static API method will be introduced to the HTMLFencedFrameElement class to check this. No fenced frame will be created when calling this API, and it can be invoked before actually attempting to create a fenced frame. The API will return a boolean, true if an opaque-ads fenced frame would be able to load in the caller's context, false if not.
A static API method will be introduced to the HTMLFencedFrameElement class to check this. No fenced frame will be created when calling this API, and it can be invoked before actually attempting to load a fenced frame config. The API will return a boolean, true if a config with an opaque mapped url would be able to load in the caller's context, false if not.

##### Example usage

Expand Down Expand Up @@ -180,11 +175,11 @@ More about security mechanisms are detailed in:
The fenced frame’s main goal is to improve privacy by disallowing communication with the embedder. There are however some attributes that might need to be shared between the two and their privacy impact needs to be carefully considered and mitigated, if possible. Some of these attributes are:


* **Initial size and resize:** To avoid the size attribute being used to communicate user identifying information from the embedding context to the fenced frame, this will be limited to only a few values. E.g. Some of the values that are relevant for ads for the "opaque-ads" mode. We are also considering allowing some of these sizes to be flexible based on the viewport width. Note that since size is a channel, these ads cannot be resized by the publisher.
* **Initial size and resize:** The API that generates a fenced frame config can pick the initial size that the fenced frame document sees, subject to whatever restrictions it deems necessary for its privacy model. If the initial size is fixed, then any changes the embedder attempts to make to the fenced frame's size will not be reflected inside of it.
* **IntersectionObserver:** It is important for ads reach and reporting APIs to know the status of the ad frame's visibility, so IntersectionObserver will need to be supported in some way, for instance by only letting it be consumed by browser APIs like [aggregate reporting API](https://github.com/csharrison/aggregate-reporting-api). We can't fully support it as iframes do, to make sure that embedding sites do not (re)position frames such that IntersectionObserver is used for communicating the user’s id to the fenced frame. This is currently under design and intersection observer capability will be supported until the alternative is provided.
* **Delegated permissions:** [Permission delegation](https://www.chromestatus.com/feature/5670617353289728) restricts permission requests to the top-level frame. Since fenced frames are embedded contexts, they should not have access to permissions, even if they are treated as top-level browsing contexts. Also delegation of permissions from the embedding context to the fenced frames should not be allowed as that could be a communication channel. This is detailed further [here](https://github.com/shivanigithub/fenced-frame/blob/master/explainer/permission_document_policies.md).
* **Network side channel:** This is detailed more here: [network side channel](https://github.com/shivanigithub/fenced-frame/blob/master/explainer/network_side_channel.md)
* **Navigation url:** Since fenced frames are allowed to open popups or navigate the top-level page in some modes, gated on user activation, the navigation url can carry bits of information out of the fenced frame tree. If the embedder and the destination are same-origin, the information in the url and embedder's info can be joined locally on navigation. This might need mitgations going forward (currently being brainstormed). Additionally, this is vulnerable to the network side channel as mentioned above when the embedding site and destnation site are colluding.
* **Navigation url:** Since fenced frames are allowed to open popups or navigate the top-level page in some use cases, gated on user activation, the navigation url can carry bits of information out of the fenced frame tree. If the embedder and the destination are same-origin, the information in the url and embedder's info can be joined locally on navigation. This might need mitgations going forward (currently being brainstormed). Additionally, this is vulnerable to the network side channel as mentioned above when the embedding site and destnation site are colluding.

More of these channels exist and the [integration with web platform](https://github.com/shivanigithub/fenced-frame/blob/master/explainer/integration_with_web_platform.md) details them further.

Expand Down
35 changes: 35 additions & 0 deletions explainer/fenced_frame_config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Fenced frame configs


## Introduction

For use cases involving APIs that access cross-site data, we need to be able to load a fenced frame with content determined by the API without revealing information about the content to the embedding context. For example, with interest-based ads in [FLEDGE](https://github.com/WICG/turtledove), the winning ad that's returned from the auction depends on the user's cross-site interest group data, which we don't want to expose to the site that calls the auction. This document proposes a web-platform way of loading content into a fenced frame using an opaque object.


## Proposed solution

`<fencedframe>` has an attribute `config`, rather than `src`. APIs like FLEDGE return a `FencedFrameConfig` object defined by our [WebIDL](https://wicg.github.io/fenced-frame/#fenced-frame-config-interface). This object has a series of fields that specify the behavior desired by the API (e.g. the ad url, width and height as seen from within the fenced frame, etc.). When the embedder stores this object into the `config` attribute, the fenced frame loads the context accordingly.

In order to hide information as described above, the browser _redacts_ `FencedFrameConfig` before sending it to the embedder. This means that certain fields which are sensitive, like the ad url, are replaced with a string `opaque`. The embedder may see whether there is a value defined for that field, but not what the value is. Likewise, when the embedder requests that a config be loaded into the fenced frame, the browser is responsible for looking up the config in a data structure in order to access the unredacted information.


### Turtledove Example

When the SSP JS invokes the Turtledove API to run the ad auction, it gets back the `FencedFrameConfig` as the result, which is then used for rendering the fenced frame. This `FencedFrameConfig` has an opaque `src`, which maps to an actual ad url which is part of the interest group.


```
navigator.runAdAuction(myAuctionConfig).then((auctionWinnerConfig) => {
// auctionWinnerConfig value e.g.
// FencedFrameConfig {
// 'src': 'opaque' ('ad.com/foo' internally)
// ...
// }
const adFrame = document.createElement('fencedframe');
adFrame.config = auctionWinnerConfig;
});
```

## Backwards compatibility

Previously we used a [`urn:uuid`](https://tools.ietf.org/html/rfc4122) and the `src` attribute to accomplish this same behavior. We will continue to support `urn:uuid` and `src` for a transition period.
10 changes: 4 additions & 6 deletions explainer/integration_with_web_platform.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
# Integration with the web platform
This document goes into the various ways in which fenced frame interacts with the platform. The web platform is massive and so we expect this document to be a running document with ongoing additions.

## Source attribute
The src attribute which defines the url of the fenced frame is subjected to various restrictons or no restrictions depending on the mode of the fenced frame. Refer the modes details [here](https://github.com/shivanigithub/fenced-frame/blob/master/explainer/modes.md) that discusses the src attribute for each of those.
## Source url
The initial source url for the fenced frame is subjected to various restrictons or no restrictions depending on the use case for the fenced frame. Refer to the use cases document [here](https://github.com/shivanigithub/fenced-frame/blob/master/explainer/use_cases.md) that discusses the source url for each of those.

## Origin
The origin of the fenced frame will be the regular origin that it got navigated to. For opaque src, the origin will be that of the url that the opaque urn was mapped to by the browser. Any origin-keyed storage and communication channels with other same-origin frames outside the fenced frame tree will be disallowed by using a partitioning key with a nonce. The storage key will use the same nonce for the nested iframes and the root fenced frame, so that same-origin channels can still work within the fenced frame tree. Essentially, along with the storage partitioning effort, the storage and broadcast channel access will be keyed on <fenced-frame-root-site, fenced-frame-root-origin, nonce> for the root frame and <fenced-frame-root-site, nested-iframe-origin, nonce> for a nested iframe. More details related to this can be found [here](https://github.com/shivanigithub/fenced-frame/blob/master/explainer/storage_cookies_network_state.md).
The origin of the fenced frame will be the regular origin that it got navigated to. For opaque src, the origin will be that of the url was mapped to by the browser. Any origin-keyed storage and communication channels with other same-origin frames outside the fenced frame tree will be disallowed by using a partitioning key with a nonce. The storage key will use the same nonce for the nested iframes and the root fenced frame, so that same-origin channels can still work within the fenced frame tree. Essentially, along with the storage partitioning effort, the storage and broadcast channel access will be keyed on <fenced-frame-root-site, fenced-frame-root-origin, nonce> for the root frame and <fenced-frame-root-site, nested-iframe-origin, nonce> for a nested iframe. More details related to this can be found [here](https://github.com/shivanigithub/fenced-frame/blob/master/explainer/storage_cookies_network_state.md).

## Size
To avoid the size attribute being used to communicate user identifying information from the embedding context to the fenced frame, this will be limited to only a few values. E.g. In the opaque-ads mode, some of the popular values that are [relevant for ads](https://support.google.com/admanager/answer/1100453?hl=en). We are also considering allowing some of these sizes to be flexible based on the viewport width on mobile.
Note that since size is a channel, these ads cannot be resized by the publisher.
TODO: The actual sizes that will be used for the "opaque-ads" fenced frame is yet to be determined and published here.
The API that generates a fenced frame config can pick the initial size that the fenced frame document sees, subject to whatever restrictions it deems necessary for its privacy model. If the initial size is fixed, then any changes the embedder makes to the width and height attributes of the <fencedframe> will not be reflected inside the fenced frame.

## Viewability
Viewability events using APIs like [Intersection Observer](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) can be a communication channel from the embedding context to the fenced frame. Viewability events are important information in the ads workflow for conversion reports and payments and would be made available in FLEDGE and other ads use cases via separate mechanisms. In the first origin trial of fenced frames, intersection observer will be fully supported and it will be phased out only when the alternative mechanism is launched.
Expand Down
4 changes: 2 additions & 2 deletions explainer/interaction_with_content_security_policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Note that this is not applicable to opaque urls which are discussed in the next

# **Opaque URL**

The first mode of fenced frames is going to be for the [opaque ads use cases](https://github.com/shivanigithub/fenced-frame/blob/master/explainer/modes.md#opaque-ads) and since the url of the fenced frame needs to be hidden from the embedding page, we cannot apply the frame-src directive directly to the mapped url, since CSP reporting can reveal to the embedding page if a fenced frame was successfully created or not. This would lead to the embedding page deriving the possible origins of the opaque ad, going against the isolation guarantees of this mode.
The first use cases for fenced frames are going to be for [opaque ads](https://github.com/WICG/fenced-frame/blob/master/explainer/use_cases.md#opaque-ads) and since the url of the fenced frame needs to be hidden from the embedding page, we cannot apply the frame-src directive directly to the mapped url, since CSP reporting can reveal to the embedding page if a fenced frame was successfully created or not. This would lead to the embedding page deriving the possible origins of the opaque ad, going against the isolation guarantees of this mode.

The other option of requiring the embedding site to mention urn:uuid (scheme of the opaque url) in their CSP rules to allow opaque ads, is also not feasible. The limitation is that there are a large number of publisher sites that currently have their csp set to e.g. `frame-src: https:` and requiring the publisher sites to change their headers in order to allow interest-group based advertising to work correctly, is not amenable to deployment.

Expand Down Expand Up @@ -119,7 +119,7 @@ A new CSP directive called fenced-frame-src to be introduced which if not presen
Content-security-policy: fenced-frame-src http://example.com ; frame-src `none`
```

# **Alternatives considered for opaque fenced frames**
# **Alternatives considered for opaque url fenced frames**
* Apply policy to the mapped URL
The alternative approach could have been to apply the csp header to the actual URL and not report it. That would be hard to roll out from a site owner’s perspective. The standard way to add or change a CSP on a site is:
1. Come up with a CSP the developer thinks is right
Expand Down

0 comments on commit f14ad02

Please sign in to comment.