1. Introduction
This section is not normative.
1.1. Recommended readings
-
The [Spectre] vulnerability.
-
The [COEP-require-corp] and [COEP-credentialless] headers.
-
How and why Cross-Origin-Opener-Policy (COOP) and Cross-Origin-Embedder-Policy (COEP) are granting the crossOriginIsolated capability. See [WhyCoopCoep].
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:
-
End users needs performant websites.
-
Some developers get performant websites, by using multithreading/
SharedArrayBuffer
in their top-level document. -
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 -
COEP requirement is recursive: third party iframes are required to deploy COEP in order to be embeddable inside a COEP parent.
-
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 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.
Storage and credentials are only shared among credentialless iframes, following normal site/origin access checks.
*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:
-
COEP:credentialless
: it means loadingno-cors
request without credentials (e.g. Cookies). -
Iframe credentialless
: it means mainly associating the document with a fresh and short lived Cookie/Network/Storage state context.
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:
-
To allow credentialless iframes to access one another if they are coming from the same origin we must maintain a mapping of original origin to opaque origin for each credentialless iframe subtree, which is complex.
-
We would probably need to standardize what happens when a frame with an opaque origin wants to access a storage API since sandboxed iframes with opaque origins do not have access to storage APIs at all.
-
It is not clear how this would interact with other checks pertaining on origin (e.g. X-Frame-Options, various CSP checks, …) potentially leading to further breakages.
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:
-
Cross-origin
<iframe>
where credentials are important. The URL is known to the parent, so it can reasonably ask its children website to be updated so that COEP and CORP headers will be sent. It can wait for the child to opt-in being embedded. -
Cross-Origin
<iframe>
like ads. The credentials do not really matters, and the parent do not really control the website being loaded.
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:
It is exposed to the Javascript HTMLIFrameElement interface:
partial interface HTMLIFrameElement {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.
partial interface Window {readonly attribute boolean credentialless ; };
6.1.3. Creating new browsing context
In the creating a new browsing context section: Add step 5:
-
Let credentialless be the result of determining the initial window credentialless flag, given browsingContext.
Then later, use it for creating a new Window.
-
For the global object, create a new Window object, with
credentialless
set to credentialless.
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:
-
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.
-
For the global object, create a new Window object, with
credentialless
set to navigationParams’s credentialless.
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.
-
If browsingContext is still on its initial about:blank Document, and navigationParams’s history handling is "replace", and browsingContext’s active document’s origin is same origin-domain with navigationParams’s origin, and browsingContext’s active window’s
credentialless
flag matches navigationParams’s credentialless flag, then do nothing.Note: This means that both the initial about:blank Document, and the new Document that is about to be created, will share the same Window object.
6.1.5. Open popup with noopener
In the window open steps, adds step 5:
-
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:
iframe
element has a mutable credentialless flag attribute. Window
has a constant credentialless
flag.
An credentialless Window is a Window
, whose credentialless
flag is true.
-
Set embedder be browsing context’s container.
-
If embedder is not an element, return false.
-
Otherwise, set parentWindow be the embedder’s node document’s relevant global object.
-
Return the union of:
-
parentWindow’s
credentialless
-
embedder’s iframe’s credentialless
-
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:
-
If target is not a child browsing context, then return true.
-
Let parentPolicy be target’s container document’s policy container’s embedder policy.
-
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. -
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.
-
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. -
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:
-
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:
6.1.9.2. For Window
In the initialize the document object, add step 6.9:
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:
It is used in step 6.
-
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:
-
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:
-
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:
-
A site.
-
null or an implementation-defined value.
-
null or a nonce.
To determine the network partition key, given an environment environment, run these steps:
-
Let topLevelOrigin be environment’s top-level origin.
-
If topLevelOrigin is null, then set topLevelOrigin to environment’s top-level creation URL’s origin.
-
Assert: topLevelOrigin is an origin.
-
Let topLevelSite be the result of obtaining a site, given topLevelOrigin.
-
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.
-
Let nonce be environment’s partition nonce
-
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].
-
Even in the absence of the "Partitioned" cookie attribute, the "partition-key" is defined and contains: (top-level-site, partition-nonce).
-
The __Host- prefix is not required.
-
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.
-
Let "partition-key" be null.
-
If If the environment's partition nonce is defined or an attribute-name case-insensitively matches the string
"Partitioned"
, then:-
Let site be the environment's top-level origin’s site.
-
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.
-
Let nonce be the environment's partition nonce.
-
Set partition-key be the tuple (site, nonce)
-
-
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.
-
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.
-
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.
-
If the cookie line also contains the [
SameParty
attribute](https://github.com/cfredric/sameparty) (the exact semantics of how theSameParty
attribute is loaded into the cookie-attribute-list is TBD) then abort the following steps and ignore the cookie entirely. -
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:
-
Let environment be the environment that initiated the request.
-
If the cookie’s partition-key is null, and environment's partition nonce is null, skip the following parts of this step.
-
Let request-top-site be the environment's top-level origin’s site.
-
Let request-partition-nonce be the environment’s partition nonce.
-
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.
-
Let request-partition-key be the tuple (request-top-site, request-partition-nonce).
-
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:
-
Let origin be environment’s origin environment’s origin if environment is an environment settings object; otherwise environment’s creation URL's origin.
-
Let nonce be environment’s partition nonce.
-
Return a tuple consisting of origin and nonce.
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.