Iframe credentialless

Draft Community Group Report,

This version:
https://wicg.github.io/anonymous-iframe/
Issue Tracking:
GitHub
Editors:
(Google)
(Google)
Tests:
web-platform-tests html/anonymous-iframe/ (ongoing work)

Abstract

Iframe credentialless gives developers a way to load documents in third party iframe using new and ephemeral network/storage/cookies context. In return, the Cross-Origin-Embedder-Policy (COEP) embedding rules can be lifted.

Developers using COEP can now embed third party iframes that do not.

Status of this document

This specification was published by the Web Platform Incubator Community Group. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups.

1. Introduction

This section is not normative.

2. A problem

This section is not normative.

Deploying COEP is difficult for some developers, because of third party iframes. Here is the typical scenario:

  1. End users needs performant websites.

  2. Some developers get performant websites, by using multithreading/SharedArrayBuffer in their top-level document.

  3. To mitigate [Spectre] attacks, browsers vendors like Chrome, Firefox and Safari gate SharedArrayBuffer usage behind the crossOriginIsolated capability. This requires deploying both COEP and COOP

  4. COEP requirement is recursive: third party iframes are required to deploy COEP in order to be embeddable inside a COEP parent.

  5. Waiting for third party to deploy COEP is painful for developers. This is often out of their control most of the time.

Beyond performance, there are additionnal features gated behind the crossOriginIsolated capability: high resolution timers, getViewportMedia, etc...

Deploying COEP is challenging in cases where there’s not a single developer involved, but many. Google Ads, for example, includes third-party content, and it seems somewhat unlikely that they’ll be able to ensure that all the ads creators will do the work to opt-into being loadable.

3. Explainer

This section is not normative.

[COEP-require-corp] currently tackles data leak attacks by ensuring that cross-origin resources explicitly opt into being loaded in an environment with higher risks. This way, servers can protect vulnerable resources by not having them opt into being loaded in high risk environments.

It would be ideal if we could find an approach that provided robust-enough protection against accidental cross-process leakage without requiring an explicit opt-in.

[COEP-credentialless] fixed the problem for simple subresources: Instead of requiring an opt-in from the response, the resource is requested without credentials. This way, only public resources are potentially leaked to the attacker. They don’t bring any additional value to the attacker.

Credentialless iframes are similar, but for <iframe>. Iframes are more difficult to tackle. They not only fetch a resource via a navigation request, but also create a new context. The new context is able to fetch data on its own. It can also access data from storage APIs: [WebStorage], [IndexedDB], [web-sql], BroadcastChannel, SharedWorker, ServiceWorker, etc

Credentialless iframes is a flag to load documents in iframes, using a new and ephemeral context. This ensures only a "public" version of the embedded website can be leaked to the attacker.

3.1. What are iframes credentialless?

Documents can create an iframe credentialless by adding an credentialless attribute to the iframe tag:

<iframe credentialless src=”https://example.com”></iframe>

This property is stored on the iframe. It is also stored and inherited to new Window loaded inside e.g.:

credentialless inheritance

Credentialless flag inheritance.

The attribute can be changed programmatically on the <iframe>. It will take effect on new Window loaded inside. It means the effect will only take place after an additional navigation.

The state of the credentialless flag is exposed to the Window through a read-only constant attribute:

window.credentialless
It is true for Window loaded immediately inside an credentialless iframe, or deeper below it.

3.2. Credentialless iframes and credentials

Iframes credentialless cannot use existing credentials and shared storage for their origin. They are given a blank slate. Unlike sandboxed frames, they can use storage APIs and register cookies. However, those credentials and storage can only be shared by documents in credentialless iframes in the page (provided they meet origin restrictions). They will no longer be accessible once the user has navigate toward a different top-level document. Essentially, credentialless iframes are given a temporary storage shelf partitioned to credentialless iframes in the current top-level document.

To achieve this, we rely on modifying the storage key used to access shared storage by credentialless iframes. As part of the client-side storage partitioning effort (declined across storage APIs, network state and Cookie State), the storage key of an environment will no longer be its simple origin as currently described in the spec. Instead it will be a combination of the origin and the top-level site URL. In an credentialless iframe, we will replace the top-level site URL in the partition key by a nonce value, determined once per top-level document. As a result, the nonce is shared for every credentialless iframe that is a descendant of the same top-level document. Because the nonce is different every time the user navigate to a different document, credentialless iframes do not share storage across different pages, or across cross-document navigations.

nonce in partition-key

Storage and credentials are only shared among credentialless iframes, following normal site/origin access checks.

page’s nonce

*Storage and credentials created by credentialless iframes are no longer accessible after the top level frame navigated away toward a different top-level document, because the Storage key for credentialless iframes will be different. It means when the top-level document is released after a navigation, the storage used by credentialless iframes can be cleared by the browser, because it will never be used anymore.

The back-forward cache can keep the top-level document and its credentialless iframe alive for longer. The nonce assigned to them continue to be used when the they are restored.

Popups opened by credentialless iframes are not credentialless. However, we impose that popups opened by credentialless iframes are opened with rel = noopener set. This is done to prevent OAuth popup flows from being used in credentialless iframes. See the threat model part for a discussion on why we impose this restriction.

3.3. How do credentialless iframes interact with COEP

Our proposition is that credentialless iframes are safe enough to embed in a COEP page, even if they haven’t opted to do so by sending a COEP header. Thus, when navigating to a document in an credentialless iframe, we do not check whether it has a COEP and CORP header, even if its parent does not have a COEP of unsafe-none.

This also means that credentialless iframes can be embedded in cross-origin isolated pages without documents in them having to deploy COEP.

3.4. Credentialless iframes and autofill/password managers

Browsers that implement autofill or password manager functionalities should make them unavailable in credentialless iframes. The goal of credentialless iframes is to preserve storage critical to an iframe function, but to avoid users logging into credentialless iframes. Autofill and password managers make logging in easier, and so should be avoided to prevent users accidentally logging in. This also allows credentialless iframes to have a threat model similar to a phishing page (see the Threat model part of this explainer below)

3.5. Comparison with COEP:credentialless

COEP:credentialless and iframe credentialless are two proposals sharing the same goal: helping developers to deploy COEP. Both are based on the idea public resources are worthless to an attacker. Public data can enter a process safely without an explicit opt-in from the server. The attacker on the same process can read the data back using Spectre, but won’t get any benefits.

The comparison do not extend further than that. The two features implementations are very different. One is for simple subresources loaded into the document, the other is for loading different documents in <iframe>.

The name credentialless means something very different:

4. Alternatives considered

This section is not normative.

4.1. Sandboxed iframe

Sandboxed iframes without the allow-same-origin flag do not have access to storage APIs or cookies for their subresource requests. However, the document of a sandbox iframe can still be requested with credentials, which does not fit the threat model. We could change sandboxed iframes so that documents are also requested without credentials.

So why are we proposing introducing a new attribute instead of just using sandboxed iframes with a new sandbox flag?

First, changing the behavior of sandboxed iframes so that their main resource is always requested without credentials could break existing websites, as opposed to introducing a new concept.

Second, we want to minimize the amount of disruption imposed to the content inside the iframe. Using sandboxed iframes means the iframes cannot use cookies or storage APIs at all, nor could they access any other frame in the document. We are worried that this would limit the deployability of the credentialless solution for opting into crossOriginIsolation. We’re looking to provide developers with a solution that is as deployable as possible, which is why we’d rather introduce a new solution that imposes as few restrictions to the iframes as possible.

We could try to codify these restrictions as a sandbox flag, e.g. allow-partitioned-storage. This is probably hard to reconcile with the storage access sandbox flag shipped by Firefox and Safari, especially since a new sandbox flag would be off by default.

This in turn is another issue with relying on sandboxed iframes for COEP deployment. Because all flags are off by default, any new flag could impact the behavior of sandboxed iframes. Not to mention that the syntax is a bit complex due to the need to add every flag but the allow-same-origin to get all functionality but access to cookies/storage.

4.2. Opaque origins

The credentialless iframes model that we propose relies on partitioned storage (see explainer), using a nonce in the storage key. We have also considered attributing opaque origins to the credentialless iframes, similar to sandboxed iframes. This would ensure that the credentialless iframes do not have access to existing credentials and shared storage since their origin has been changed to an opaque one.

This solution runs into compatibility issues:

4.3. Make COEP:credentialless to affect <iframe>

Originally, COEP:credentialless scope was meant to include both simple subresources like it does today, but also the <iframe>. The latter is very different in kind, because this is not only about the request’s credentials, but also about every storage API usage made later by the document. So it has been postponed here.

The difficulty is that most of the time, a website will include a mix of:

So, it is important for the parent to be able to make the decision on a per-iframe basis. Please note that the decision can never be made directly by the children, because this affects the navigation’s request’s credentials. It would be too late.

With COEP:credentialless, site authors can decide to send credentials on a per-resource basis, by tweaking the request.mode and decide in between cors and no-cors. One requires the subresource to opt-in being embedded, the other omit credentials.

We need a similar mechanism for the <iframe> element. This became the credentialless attribute as a result.

5. Tests

Status: https://wpt.fyi/results/html/credentialless-iframe/

6. Specification

6.1. Integration with HTML

Note: This corresponds to the following HTML specification change: whatwg/html/pull/7695.
When merged this section will become obsolete.

6.1.1. The Iframe attribute

In the the iframe element section, define the HTML iframe credentialless attribute:

The credentialless attribute, enables loading documents hosted by the iframe with a new and ephemeral storage partition. It is a boolean value. The default is false.

It is exposed to the Javascript HTMLIFrameElement interface:

[Exposed=Window]
interface HTMLIFrameElement : HTMLElement {
  // [...]
  attribute boolean credentialless;
  // [...]
};

The IDL attributes credentialless, must reflect the respective content attributes of the same name.

6.1.2. The Window attribute

Add a read-only constant credentialless attribute to the Window object.

[
  Global=Window,
  Exposed=Window,
  LegacyUnenumerableNamedProperties
]
interface Window : EventTarget {
  // ...
  readonly attribute boolean credentialless;
  // ...
};

6.1.3. Creating new browsing context

In the creating a new browsing context section: Add step 5:

  1. Let credentialless be the result of determining the initial window credentialless flag, given browsingContext.

Then later, use it for creating a new Window.

6.1.4. Navigating a browsing context

In the navigation params struct, adds the credentialless parameter:

credentialless
The credentialless flag to impose on the new Window

In the navigate algorithm, adds step 18:

  1. Let credentialless be the result of computing the navigation’s credentialless flag, given browsingContext.

Then later in the same algorithm, use this variable to build the navigation params.

It is also passed as a new argument to the process a navigate fetch algorithm, which is also used to create a new navigation params.


Then, in the initialize the document object algorithm:

When creating a new Window in the browsing context, pass the credentialless value.


The Window object must not be reused, when it would lead to keeping an credentialless flag different from what is in the navigation params.

Example: This is useful in this case:

const iframe = document.body.createElement("iframe");
iframe.credentialless = true;
document.body.appendChild(iframe);
iframe.credentialless = false;
iframe.src = "https://example.test";
// Window for about:blank and for https://example.test must be different.

6.1.5. Open popup with noopener

In the window open steps, adds step 5:

  1. If entry global object’s credentialless flag is true, then set noopener to true.

6.1.6. General section

Add an "Credentialless iframe" sub-section inside Loading web pages section, in between the Sandboxing one and the Sandboxing one and the Cross-origin opener policies ones:

7.7 Credentialless iframe
Each iframe element has a mutable credentialless flag attribute.
Each Window has a constant credentialless flag.

An credentialless Window is a Window, whose credentialless flag is true.

To compute the initial window credentialless flag, given a new browsing context browsing context:
  1. Set embedder be browsing context’s container.

  2. If embedder is not an element, return false.

  3. Otherwise, set parentWindow be the embedder’s node document’s relevant global object.

  4. Return the union of:

To compute the navigation’s credentialless flag, given browsing context browsing context, follows the same steps as in the initial window credentialless flag algorithm.

Add several notes in the general section, gathering changes spread elsewhere in the other algorithms.

Note: New Window's credentialless flag is computed either from the initial window credentialless flag algorithm for new browsing context, or from the navigation’s credentialless flag algorithm, executed when the navigation started, for navigations inside pre-existing browsing context.

Note: Popup opened from credentialless Window are always with noopener set.

Note: Top-level credentialless Window do not exist.

6.1.7. COEP embedder checks

The COEP embedding checks can be lifted.

Add a new parameters credentialless parameter to the check a navigation response’s adherence to its embedder policy and pass navigationParams’s credentialless.

To check a navigation response’s adherence to its embedder policy given a response response, a browsing context target, an embedder policy responsePolicy, and a boolean credentialless:

  1. If target is not a child browsing context, then return true.

  2. Let parentPolicy be target’s container document’s policy container’s embedder policy.

  3. If parentPolicy’s report-only value is compatible with cross-origin isolation and responsePolicy’s value is not, and credentialless is false, then queue a cross-origin embedder policy inheritance violation with response, "navigation", parentPolicy’s report only reporting endpoint, "reporting", and target’s container document’s relevant settings object.

  4. If parentPolicy’s value is not compatible with cross-origin isolation or responsePolicy’s value is compatible with cross-origin isolation, or credentialless is true, then return true.

  5. Queue a cross-origin embedder policy inheritance violation with response, "navigation", parentPolicy’s reporting endpoint, "enforce", and target’s container document’s relevant settings object.

  6. Return false.

6.1.8. Autofill

In the "Credentialless iframe" section. Defining the how web browser should configure their autofilling features.

Autofill and credentialless iframe: User agents sometimes have features for helping users fill forms in: for example prefilling the user’s address, password, or payment informations. User agents must disable those features when the data is both specific to the user and to the website.

6.1.9. Environment’s partition nonce

In the "Credentialless iframe" section. Defining the page credentialless nonce.

Each top-level Window has an associated page credentialless nonce. It is an immutable nonce ("number used once").

Add the partition nonce attribute to the environment object.

A partition nonce

An identifier or null. This is used to discriminate and isolate environments further. Among others, it is non null for credentialless Window

6.1.9.1. For Navigation

In the process a navigate fetch, add step:

  1. If credentialless is true, let partitionNonce be browsingContext’s top-level browsing context’s page credentialless nonce, null otherwise.

partitionNonce is used later to create the Environment. Modify step 13.3.4:

13.3.4. Set request’s reserved client to a new environment whose id is a unique opaque string, target browsing context is browsingContext, creation URL is currentURL, top-level creation URL is topLevelCreationURL, top-level origin is topLevelOrigin, and partition nonce is partitionNonce
.
6.1.9.2. For Window

In the initialize the document object, add step 6.9:

6.9. If navigationParams’s credentialless is true, let partitionNonce be browsingContext’s top-level browsing context’s page credentialless nonce, null otherwise.

Then, plumb it to create the Environment in step 6.10:

6.10 Set up a window environment settings object with creationURL, realm execution context, navigationParams’s reserved environment, topLevelCreationURL, topLevelOrigin, and partitionNonce.

partitionNonce is passed to the set up a window environment settings object this way:

To set up a window environment settings object, given a URL creationURL, a JavaScript execution context execution context, null or an environment reservedEnvironment, a URL topLevelCreationURL, an origin topLevelOrigin, and an identifier partitionNonce run these steps:

It is used in step 6.

  1. Set settings object’s creation URL to creationURL, settings object’s top-level creation URL to topLevelCreationURL, settings object’s top-level origin to topLevelOrigin, and settings object’s partition nonce to partitionNonce.

6.1.9.3. For Worker

In the script settings for workers algorithm, add step 8:

  1. Set settings object’s partition nonce to outside settings’s partition nonce.

6.1.9.4. For Worklet

In the set up a worklet environment settings object algorithm, modify step 7:

  1. Set settingsObject’s id to a new unique opaque string, creation URL to inheritedAPIBaseURL, top-level creation URL to null, top-level origin to outsideSettings’s top-level origin, partition nonce to outsideSettings’s partition nonce, target browsing context to null, and active service worker to null.

6.2. Integration with Fetch

Note: This corresponds to the following HTML specification change: whatwg/fetch/pull/1416.
When merged this section will become obsolete.

6.2.1. Plumb the partition-nonce

Add the environment's partition nonce into the network partition key. Proceed the following changes:

A network partition key is a tuple consisting of:

To determine the network partition key, given an environment environment, run these steps:

  1. Let topLevelOrigin be environment’s top-level origin.

  2. If topLevelOrigin is null, then set topLevelOrigin to environment’s top-level creation URL’s origin.

  3. Assert: topLevelOrigin is an origin.

  4. Let topLevelSite be the result of obtaining a site, given topLevelOrigin.

  5. Let secondKey be null or an implementation-defined value.

    The second key is intentionally a little vague as the finer points are still evolving. See issue #1035.

  6. Let nonce be environment’s partition nonce

  7. Return (topLevelSite, secondKey, nonce).

6.3. Integration with CHIPS

This section defines a monkey-patch over: [CHIPS], which is itself a monkey-patch over [COOKIES].

Note / Summary: Cookies Having Independent Partitioned State (CHIPS) introduce the cookie’s partition key. To implement credentialless iframe, when the environment's partition nonce is defined:
  1. Even in the absence of the "Partitioned" cookie attribute, the "partition-key" is defined and contains: (top-level-site, partition-nonce).

  2. The __Host- prefix is not required.

  3. The environment only have access to cookies whose "partition-key" is defined.

Modify the [CHIPS] section: https://github.com/WICG/CHIPS/blob/main/README.md#algorithm

Below is the algorithm that browsers can use to parse cookie lines. This algorithm could be added to section 5.3 of RFC6265bis.

  1. Let "partition-key" be null.

  2. If If the environment's partition nonce is defined or an attribute-name case-insensitively matches the string "Partitioned", then:

    1. Let site be the environment's top-level origin’s site.

    2. If site is in a First-Party Set, then set site be the concatenation of "https://" and the "owner domain" of the site’s set.

    3. Let nonce be the environment's partition nonce.

    4. Set partition-key be the tuple (site, nonce)

  3. Append an attribute to the cookie-attribute-list with an attribute-name of "PartitionKey" and an attribute-value of partition-key.

Below is the algorithm for storing Partitioned cookies. These steps could be added to section 5.4 of RFC6265bis after the user agent processes the cookie’s __Host- prefix.

  1. If the cookie-attribute-list contains an attribute with an attribute-name of "PartitionKey", and attribute-value is null or a tuple (site, nonce), with a non-null nonce, then skip the following steps and insert the cookie into the cookie store.

  2. If the cookie-name does not start with a case-sensitive match for the string "__Host-", then abort the following steps and ignore the cookie entirely.

  3. If the cookie line also contains the [SameParty attribute](https://github.com/cfredric/sameparty) (the exact semantics of how the SameParty attribute is loaded into the cookie-attribute-list is TBD) then abort the following steps and ignore the cookie entirely.

  4. Set the cookie’s partition-key to the attribute-value of the element in the attribute-list whose attribute-name is "PartitionKey".

Below is an algorithm for attaching Partitioned cookies to a request. These steps could be added to the algorithm described in section 5.5 of RFC6265bis after the first step.

For each cookie in the cookie-list do the following:

  1. Let environment be the environment that initiated the request.

  2. If the cookie’s partition-key is null, and environment's partition nonce is null, skip the following parts of this step.

  3. Let request-top-site be the environment's top-level origin’s site.

  4. Let request-partition-nonce be the environment’s partition nonce.

  5. If request-top-site is in a First-Party Set, then set request-top-site be the concatenation of "https://" and the "owner domain" of the request-top-site’s set.

  6. Let request-partition-key be the tuple (request-top-site, request-partition-nonce).

  7. If the cookie’s partition-key is not an exact match of request-partition-key, then remove that cookie from the cookie-list.

6.4. Integration with storage-partitioning

In the [StoragePartition] (link) Work Item. Most storage APIs will be keyed by an additional key: the top-level site.

To implement credentialless iframe, another key should be added and defined as the environment's partition nonce.

nonce
The environment's partition nonce

6.5. Integration with storage

Note: This corresponds to the following [STORAGE] specification change: whatwg/storage/pull/139.
When merged this section will become obsolete.

6.5.1. storage-key

Add the environment's partition nonce as an additional key in the storage key.

A storage key is a tuple consisting of:

To obtain a storage key for non-storage purposes, given an environment environment, run these steps:

7. Security considerations

7.1. Threat model

Because credentialless iframes can be embedded in crossOriginIsolated contexts, in browsers without Out-of-Process-Iframes, we have to consider that their embedder can perform a [Spectre] attack to read any of the credentialless iframes resources, including the HTML. The victim is the document loaded inside the credentialless iframe and the other documents are the attackers.

Our approach to this threat is not to prevent the attack from happening, but to avoid loading personalized data so that an attacker has only access to publicly available data.

To do so, we consider a variety of possible attacks:

7.2. Usage of existing credentials

The most dangerous attack is also the most straightforward. The attacker embeds an credentialless iframe with resources for which the user already has credentials. The attacker then reads the personalized resources inside the iframe, which are not public data.

Mitigation:

Credentialless iframes do not have access to existing credentials stored by their origin. This includes cookies. This also includes any data in the origin shared storage, as it could have been retrieved using credentials, hence personalized. Credentialless iframes start from a blank slate to prevent an attacker from loading resources using existing credentials.

7.3. Usage of new credentials

In this attack, the attacker embeds an credentialless iframe. As explained above, the credentialless iframe starts from a blank slate when it comes to credentials and shared storage. However, the credentialless iframe could register new credentials and use those to request personalized resources. The attacker can then read those. In practice, we can divide this scenario into two. First usage of credentials storing state necessary to make the iframe site work, but which is not particular to a user. This case is not problematic, as it is publicly accessible data. The second one is state personalized by user, which would be acquired after the user logs into the credentialless iframe.

Finally, there is the question of how long such credentials should persist, and how they should be shared across credentialless iframes. For example, one could imagine that the user visits a legitimate page with an credentialless iframe A where they log in. Then they visit an attacker page with an credentialless iframe of the same origin A. If they are still logged into A, the attacker page could steal data from personalized subresources.

Mitigation:

If the user is directly typing their credentials in the iframe to log-in, they are logging into the iframe, in a page with a different URL shown in the omnibox. This is similar to a phishing attack both in user action needed for the attack to happen and outcome. This case shouldn’t require extra-mitigation.

When the user is using a popup-driven OAuth flow (or the upcoming WebID API), the situation is harder to understand from the user’s perspective. To prevent this from happening, we restrict the iframe ability to open popups (e.g. all popups are opened with no-opener set), and access the WebID API when it ships.

In terms of lifetime and sharing of credentials, they are bound to the lifetime of the credentialless iframe. So if a page creates an credentialless iframe, documents in the subtree of the credentialless iframe get a clean slate of credentials and shared storage. Documents in the subtree can create credentials. They can share them among themselves (as long as they respect the same-origin policy), and only among themselves. So if two pages are opened at the same time with two credentialless iframes with the same origin, the credentialless iframes cannot share their credentials. Once the credentialless iframe is destroyed, the credentials that were created in its subtree should no longer be accessible. This ensures that we preserve as much functionality for the credentialless iframe as possible, while minimizing the risk of accidentally leaking data.

7.4. Personalized resources based on network position

This is a variant of the previous attack, where the user embeds an iframe with private subresources the user is only allowed to access due to their network position. For example, resources found on the user private network, or resources personalized based on a user IP address.

Mitigation:

We plan on dealing with the private network case by deploying Private Network Access restrictions. During the CORS preflight introduced by Private Network Access restrictions, the servers will be able to check that their resource will be rendered in an credentialless iframe context by checking the Sec-Fetch-COEP header. Note that only local-network documents which enable HTTPS could potentially be exposed (because MIX should prevent HTTP resources from being loaded by a page with COI). This isn’t a strong mitigation, but will matter for things like common IoT devices. The other cases of resources personalized based on IP address are arguably a security footgun already. We think that the increased risk there is okay compared to the advantage of not using credentials on more requests overall.

7.5. Capture of user input

In this attack, the attacker embeds an credentialless iframe that can receive user input. It then reads the user input.

Mitigation:

This is not in scope for credentialless iframes. An attacker can already do a phishing attack where they construct a fake page using publicly available resources and trick the user into entering data. This attack is equivalent, since the URL shown to the user in the navigation bar will still be that of the attacker.

7.6. Credentialless iframes using side-channels to personalize themselves

The credentialless iframe could use side-channels (e.g. broadcast channels, postMessage) to attempt to get a form of personalization despite the lack of credentials. The personalized resources are then readable by the embedder.

Mitigation:

Depending on whether the mechanisms highlighted above are a common way of personalizing resources, this might be out-of-scope. What we want to defend against is unsuspecting websites being embedded and attacked by their embedder to steal user data. If the credentialless iframe is bent on escaping the constraints of credentialless iframes to personalize itself, then one can argue that it understands the contexts and risks it is loaded in and accepts them. Provided our security model is safe enough outside of credentialless iframes, the personalization will only affect resources that are same-origin with the iframe anyway. Cross-origin resources to the framed document will still be unpersonalized, making this equivalent to COEP:credentiallesss from a security perspective.

8. Privacy considerations

The main privacy threat posed by this API is the risk of a data leak through a side channel attack like [Spectre]. As detailed in the threat model above, we believe the API provides a meaningful defense against [Spectre] attacks, and thus does not pose a privacy risk.

9. Self-Review Questionnaire

See [SecurityPrivacyQuestionnaire] (link)

9.1. What information might this feature expose to Web sites or other parties, and for what purposes is that exposure necessary?

The window.credentialless method exposes whether a document is loaded in an credentialless iframe or not, allowing a document to change its behavior depending on the availability of existing credentials or stored resources.

9.2. Do features in your specification expose the minimum amount of information necessary to enable their intended uses?

Yes. The only thing exposed is whether a document is embedded inside an credentialless iframe or not.

9.3. How do the features in your specification deal with personal information, personally-identifiable information (PII), or information derived from them?

The feature does not deal with PII.

9.4. How do the features in your specification deal with sensitive information?

The feature does not deal with sensitive information.

9.5. Do the features in your specification introduce new state for an origin that persists across browsing sessions?

No the feature does not introduce new state for an origin.

9.6. Do the features in your specification expose information about the underlying platform to origins?

No the feature behaves the same regardless of the underlying platform.

9.7. Does this specification allow an origin to send data to the underlying platform?

No this feature does not change what data an origin is allowed to send to the underlying platform.

9.8. Do features in this specification allow an origin access to sensors on a user’s device?

No the feature has no impacty on sensor access.

9.9. Do features in this specification enable new script execution/loading mechanisms?

No the feature does not enable new script execution/loading.

9.10. Do features in this specification allow an origin to access other devices?

No the feature is strictly confined to one device.

9.11. Do features in this specification allow an origin some measure of control over a user agent’s native UI?

No the feature has no impact on UI.

9.12. What temporary identifiers do the feautures in this specification create or expose to the web?

No temporary identifiers are created.

9.13. How does this specification distinguish between behavior in first-party and third-party contexts?

There is no distinction between first-party and third-party ability to embed credentialless iframes. This is due to the recursive nature of COEP. To deploy COEP in a frame, all child frames need to deploy COEP first. Since this is a mechanism to help with the deployment of COEP, we want to offer third-party iframes the option to ease their own COEP deployment by being able to embed their own third party content as credentialless iframes.

9.14. How do the features in this specification work in the context of a browser’s Private Browsing or Incognito mode?

No difference with regular mode.

9.15. Does this specification have both "Security Considerations" and "Privacy Considerations" sections?

Yes:

9.16. Do features in your specification enable origins to downgrade default security protections?

This feature has no impact on secure context and same-origin policy. It does allow to use features which are right now gated behind having COOP and COEP enabled. However, it imposes restrictions on documents to make this safe.

9.17. How does your feature handle non-"fully active" documents?

Credentialless iframe only affect documents inside iframes. It is a general assumption back/forward cache features are implemented only for main frame navigations. With this assumption, there is nothing special to do.

Hypothetical web browsers implementing back/forward cache at the sub-frame level must definitively think about what happens when restoring a document inside an iframe whose "credentialless" attribute has changed. For instance, they could prevent the back/forward cache from restoring the document.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[CHIPS]
Dylan Cutler; Kaustubha Govind. CHIPS (Cookies Having Independent Partitioned State). URL: https://github.com/WICG/CHIPS
[COOKIES]
Mike West; John Wilander. Cookies: HTTP State Management Mechanism. URL: https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-07
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript Language Specification. URL: https://tc39.es/ecma262/multipage/
[FETCH]
Anne van Kesteren. Fetch Standard. Living Standard. URL: https://fetch.spec.whatwg.org/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[STORAGE]
Storage. URL: https://storage.spec.whatwg.org/
[StoragePartition]
Client-Side Storage Partitioning. URL: https://privacycg.github.io/storage-partitioning/
[URL]
Anne van Kesteren. URL Standard. Living Standard. URL: https://url.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

Informative References

[COEP-credentialless]
Arthur Sonzogni; et al. COEP: credentialless. URL: https://wicg.github.io/cross-origin-embedder-policy/
[COEP-require-corp]
Mike West. COEP. URL: https://wicg.github.io/cross-origin-embedder-policy/
[IndexedDB]
Nikunj Mehta; et al. Indexed Database API. URL: https://w3c.github.io/IndexedDB/
[SecurityPrivacyQuestionnaire]
Theresa O’Connor; et al. Self-Review Questionnaire: Security and Privacy. URL: https://www.w3.org/TR/security-privacy-questionnaire/
[Spectre]
Paul Kocher; et al. Spectre Attacks: Exploiting Speculative Execution. URL: https://spectreattack.com/spectre.pdf
[WEB-SQL]
Ian Hickson. Web SQL Database. 18 November 2010. NOTE. URL: https://www.w3.org/TR/webdatabase/
[WebStorage]
Ian Hickson. Web Storage (Second Edition). URL: https://w3c.github.io/webstorage/
[WhyCoopCoep]
Eiji Kitamura; Demenic Denicola. Why you need "cross-origin isolated" for powerful features. URL: https://web.dev/why-coop-coep/

IDL Index

[Exposed=Window]
interface HTMLIFrameElement : HTMLElement {
  // [...]
  attribute boolean credentialless;
  // [...]
};

[
  Global=Window,
  Exposed=Window,
  LegacyUnenumerableNamedProperties
]
interface Window : EventTarget {
  // ...
  readonly attribute boolean credentialless;
  // ...
};