无凭据 iframe

社区组报告草案

此版本:
https://wicg.github.io/anonymous-iframe/
问题跟踪:
GitHub
编辑:
Google
Google
测试:
web-platform-tests html/anonymous-iframe/进行中的工作

摘要

无凭据 iframe 为开发者提供了一种方式,可以在第三方 iframe 中使用新的、临时的网络/存储/cookie 上下文加载文档。作为回报,Cross-Origin-Embedder-Policy(COEP) 嵌入规则可以放宽。

使用 COEP 的开发者现在可以嵌入未使用 COEP 的第三方 iframe。

本文档状态

本规范由 Web Platform Incubator Community Group 发布。 它不是 W3C 标准,也不在 W3C 标准轨道上。 请注意,根据 W3C 社区 贡献者许可协议(CLA),存在有限的退出机制,并适用其他条件。 了解更多关于 W3C 社区组和商务组 的信息。

1. 引言

本节不是规范性的。

2. 一个 问题

本节不是规范性的。

对某些开发者而言,部署 COEP 很困难,因为存在第三方 iframe。典型场景如下:

  1. 最终用户需要高性能网站。

  2. 一些开发者通过在其顶级文档中使用 多线程/SharedArrayBuffer 来获得高性能网站。

  3. 为了缓解 [Spectre] 攻击,Chrome、Firefox 和 Safari 等浏览器厂商将 SharedArrayBuffer 的使用置于 crossOriginIsolated 能力之后。这要求同时部署 COEPCOOP

  4. COEP 要求是递归的:第三方 iframe 必须 部署 COEP,才能被嵌入到 COEP 父级中。

  5. 等待第三方部署 COEP 对开发者来说很痛苦。 大多数时候这通常不受他们控制。

除性能之外,还有其他功能也受 crossOriginIsolated 能力门控:高分辨率计时器getViewportMedia 等……

在并非只有一个开发者参与,而是有许多开发者参与的情况下,部署 COEP 很有挑战。例如 Google Ads 包含第三方内容, 而且他们似乎不太可能确保所有广告创作者都会完成选择加入可加载状态的工作。

3. 解释说明

本节不是规范性的。

[COEP-require-corp] 目前 通过确保跨源资源显式选择加入在风险更高的环境中加载,来应对数据泄漏攻击。 这样,服务器可以通过不让易受攻击的资源选择加入在高风险环境中加载, 来保护这些资源。

如果我们能找到一种方法,在不需要显式选择加入的情况下,提供足够稳健的保护以防意外的跨进程泄漏, 那会很理想。

[COEP-credentialless] 解决了简单子资源的问题: 不再要求响应进行选择加入,而是以无凭据的方式请求该资源。 这样,只有公共资源可能泄漏给攻击者。它们不会给攻击者带来任何额外价值。

无凭据 iframe 类似,但用于 <iframe>。 iframe 更难处理。它们不仅通过导航请求获取资源, 还会创建新的上下文。这个新上下文能够自行获取数据。 它还可以访问来自存储 API 的数据:[WebStorage][IndexedDB][web-sql]BroadcastChannelSharedWorkerServiceWorker

无凭据 iframe 是一个用于在 iframe 中加载文档的标志,它使用新的、 临时的上下文。这确保只有嵌入网站的“公共”版本可能泄漏给攻击者。

3.1. 什么是无凭据 iframe?

文档可以通过向 iframe 标签添加 credentialless 属性来创建无凭据 iframe:

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

此属性存储在 iframe 上。它也会被存储并继承到内部加载的新 Window,例如:

credentialless inheritance

无凭据标志继承。

可以在 <iframe> 上以编程方式更改该属性。它会对内部新加载的 Window 生效。这意味着该效果只会在一次额外导航之后发生。

无凭据标志的状态通过只读常量属性暴露给 Window

window.credentialless

对于直接加载在无凭据 iframe 内的 Window,或其更深层级内的 Window,该值为 true。

3.2. 无凭据 iframe 与凭据

无凭据 iframe 不能使用其源的现有凭据和共享存储。 它们被赋予一个空白状态。与沙盒化 frame 不同,它们可以 使用存储 API 并注册 cookie。不过,这些凭据和存储 只能由页面中的无凭据 iframe 内的文档共享(前提是 它们满足源限制)。一旦用户导航到不同的顶级文档, 它们将不再可访问。本质上,无凭据 iframe 会得到一个临时的 storage shelf,该 storage shelf 被分区给 当前顶级文档中的无凭据 iframe。

为实现这一点,我们依赖于修改无凭据 iframe 用于访问共享存储的 storage key。作为 客户端存储分区 工作 的一部分(横跨 存储 API网络 状态Cookie 状态 递延),环境的 storage key 将不再是规范当前描述的简单源。相反,它将是源与顶级站点 URL 的组合。 在无凭据 iframe 中,我们会用一个 nonce 值替换分区键中的顶级站点 URL, 该 nonce 值对每个顶级文档确定一次。因此,作为同一顶级文档后代的每个 无凭据 iframe 都共享该 nonce。由于每次用户导航到不同文档时 nonce 都不同, 无凭据 iframe 不会在不同页面之间,或跨跨文档导航共享存储。

nonce in partition-key

存储和凭据只在无凭据 iframe 之间共享,并遵循正常的站点/源访问检查。

page’s nonce

*无凭据 iframe 创建的存储和凭据在顶级 frame 导航离开到不同的顶级文档之后不再可访问, 因为无凭据 iframe 的 Storage key 将不同。 这意味着当顶级文档在导航后被释放时,浏览器可以清除 无凭据 iframe 使用的存储,因为它将再也不会被使用。

往返缓存可以让顶级文档及其无凭据 iframe 存活更久。分配给它们的 nonce 在它们被恢复时会继续使用。

由无凭据 iframe 打开的弹出窗口不是无凭据的。不过,我们 强制由无凭据 iframe 打开的弹出窗口以设置了 rel = noopener 的方式打开。这样做是为了防止 OAuth 弹出窗口流程被用于 无凭据 iframe。关于我们为什么施加此限制的讨论,见威胁模型部分。

3.3. 无凭据 iframe 如何与 COEP 交互

我们的提议是,无凭据 iframe 足够安全,可以嵌入到 COEP 页面中,即使它们没有通过发送 COEP 标头选择加入。因此, 当导航到无凭据 iframe 中的文档时,即使其父级的 COEP 不是 unsafe-none,我们也不会检查它是否具有 COEP 和 CORP 标头。

这也意味着,无凭据 iframe 可以嵌入到跨源 隔离页面中,而其中的文档无需部署 COEP。

3.4. 无凭据 iframe 与自动填充/密码管理器

实现自动填充或密码管理器功能的浏览器应使 这些功能在无凭据 iframe 中不可用。无凭据 iframe 的目标 是保留对 iframe 功能至关重要的存储,但避免用户 登录无凭据 iframe。自动填充和密码管理器会让登录 更容易,因此应避免使用,以防用户意外登录。 这也允许无凭据 iframe 具有类似于 钓鱼页面的 威胁模型(见下方本解释说明的 威胁 模型部分)

3.5. 与 COEP:credentialless 的比较

COEP:credentiallessiframe credentialless 是两个具有相同目标的提案: 帮助开发者部署 COEP。二者都基于这样一个想法: 公共资源对攻击者没有价值。公共数据可以在没有服务器显式选择加入的情况下安全地进入进程。 同一进程中的攻击者可以使用 Spectre 读取这些数据,但不会获得任何收益。

比较到此为止。这两个功能的实现 非常不同。一个用于加载到文档中的简单子资源, 另一个用于在 <iframe> 中加载不同的文档。

credentialless 这个名称含义非常不同:

4. 已考虑的替代方案

本节不是规范性的。

4.1. 沙盒化 iframe

没有 allow-same-origin 标志的沙盒化 iframe 无权访问 存储 API 或其子资源请求的 cookie。不过,sandbox iframe 的文档 仍可带凭据请求,这不符合威胁模型。我们可以更改沙盒化 iframe, 使文档也在无凭据的情况下被请求。

那么,为什么我们提议引入一个新属性,而不是只使用 带有新 sandbox 标志的沙盒化 iframe?

首先,改变沙盒化 iframe 的行为,使其主资源 总是在无凭据的情况下被请求,可能会破坏现有网站;而引入新概念则不会。

其次,我们希望尽量减少对 iframe 内部内容施加的干扰。 使用沙盒化 iframe 意味着这些 iframe 完全不能使用 cookie 或存储 API,也不能访问文档中的任何其他 frame。 我们担心这会限制无凭据方案在选择加入 crossOriginIsolation 时的可部署性。 我们希望为开发者提供一种尽可能可部署的方案,因此我们更倾向于引入一种新的方案, 对 iframe 施加尽可能少的限制。

我们可以尝试将这些限制编纂为一个 sandbox 标志,例如 allow-partitioned-storage。这可能很难与 Firefox 和 Safari 已经发布的 storage access sandbox 标志协调,尤其是因为新的 sandbox 标志默认会关闭。

这反过来也是依赖沙盒化 iframe 进行 COEP 部署的另一个问题。由于所有标志默认都是关闭的,任何新标志都可能影响 沙盒化 iframe 的行为。更不用说语法有点复杂, 因为需要添加除 allow-same-origin 之外的每个标志,才能获得 除访问 cookie/存储之外的所有功能。

4.2. 不透明源

我们提出的无凭据 iframe 模型依赖于分区存储 (见解释说明),在 storage key 中使用 nonce。我们也曾考虑 为无凭据 iframe 分配不透明源,类似于沙盒化 iframe。这将确保无凭据 iframe 无权访问 现有凭据和共享存储,因为它们的源已被更改为 不透明源。

这个方案会遇到兼容性问题:

4.3. 使 COEP:credentialless 影响 <iframe>

最初,COEP:credentialless 的范围本意是既包含如今这样的简单 子资源,也包含 <iframe>。后者在性质上非常不同, 因为这不仅关乎请求的凭据,还关乎文档之后使用的每个存储 API。 因此它在此处被推迟。

困难在于,大多数时候,一个网站会包含如下混合内容:

因此,父级能够按每个 iframe 作出决定非常重要。 请注意,决策永远不能由子级直接作出, 因为这会影响导航请求的凭据。那样就太晚了。

使用 COEP:credentialless 时,站点作者可以通过调整 request.mode 并在 corsno-cors 之间决定,来按每个资源决定是否发送凭据。 一个要求子资源选择加入被嵌入,另一个则省略凭据。

对于 <iframe> 元素,我们需要类似机制。结果就形成了 credentialless 属性。

5. 测试

状态:https://wpt.fyi/results/html/credentialless-iframe/

6. 规范

6.1. 与 HTML 集成

注: 这对应于以下 HTML 规范更改:whatwg/html/pull/7695
合并后,本节将过时。

6.1.1. Iframe 属性

iframe 元素 章节中,定义 HTML iframecredentialless 属性:

credentialless 属性启用使用 新的、临时的存储分区来加载由 iframe 托管的文档。 它是一个布尔值。默认值为 false。

它暴露给 Javascript HTMLIFrameElement 接口:

partial interface HTMLIFrameElement {
  attribute boolean credentialless;
};

IDL 属性 credentialless 必须反映同名的对应内容属性。

6.1.2. Window 属性

Window 对象添加只读常量 credentialless 属性。

partial interface Window {
  readonly attribute boolean credentialless;
};

6.1.3. 创建新的浏览上下文

创建新的浏览上下文 章节中: 添加步骤 5:

  1. credentialless 为在给定 browsingContext 时确定初始 window credentialless 标志的结果。

随后,在创建新的 Window 时使用它。

6.1.4. 导航浏览上下文

navigation params 结构中,添加 credentialless 参数:

credentialless
要强加给新的 Windowcredentialless 标志

navigate 算法中,添加步骤 18:

  1. credentialless 为在给定 browsingContext 时计算导航的 credentialless 标志的结果。

随后在同一算法中,使用此变量来构建 navigation params

它还作为新实参传递给 process a navigate fetch 算法,该算法也用于 创建新的 navigation params


然后,在 initialize the document object 算法中:

浏览上下文中创建新的 Window 时,传递 credentialless 值。


当重用 Window 对象会导致保留与 navigation params 中不同的 credentialless 标志时,不得重用该对象。

示例:这在以下情况下很有用:

const iframe = document.body.createElement("iframe");
iframe.credentialless = true;
document.body.appendChild(iframe);
iframe.credentialless = false;
iframe.src = "https://example.test";
// about:blank 和 https://example.test 的 Window 必须不同。

6.1.5. 使用 noopener 打开弹出窗口

window open steps 中,添加步骤 5:

  1. 如果 entry global objectcredentialless 标志为 true,则将 noopener 设置为 true。

6.1.6. 通用小节

加载 web 页面章节内添加一个 "Credentialless iframe" 子章节,位于 Sandboxing oneSandboxing oneCross-origin opener policies 章节之间:

7.7 Credentialless iframe
每个 iframe 元素都有一个可变的 credentialless 标志属性。
每个 Window 都有一个常量 credentialless 标志。

无凭据 Window 是一个 Window, 其 credentialless 标志为 true。

要计算初始 window credentialless 标志,给定新的 浏览 上下文 browsing context
  1. embedder 设置为 browsing context容器

  2. 如果 embedder 不是元素,则返回 false。

  3. 否则,将 parentWindow 设置为 embedder节点 文档相关全局对象

  4. 返回以下二者的并集:

要计算导航的 credentialless 标志, 给定 浏览上下文 browsing context,遵循与初始 window credentialless 标志算法相同的步骤。

在通用小节中添加几条注,汇集分散在其他算法中的更改。

注:Windowcredentialless 标志,要么由用于新 浏览上下文初始 window credentialless 标志算法计算, 要么由在导航开始时执行、用于预先存在的 浏览上下文内导航的导航的 credentialless 标志算法计算。

注:无凭据 Window 打开的弹出窗口 总是设置 noopener

注: 顶级无凭据 Window 不存在。

6.1.7. COEP 嵌入器检查

COEP 嵌入 检查可以放宽。

check a navigation response’s adherence to its embedder policy 添加新的 credentialless 参数, 并传递 navigationParamscredentialless

要在给定 响应 response浏览上下文 target嵌入器策略 responsePolicy以及布尔值 credentialless 的情况下检查导航 响应对其嵌入器策略的遵循情况

  1. 如果 target 不是子浏览上下文,则 返回 true。

  2. parentPolicytarget容器文档策略容器嵌入器策略

  3. 如果 parentPolicyreport-only 值兼容 跨源隔离,且 responsePolicy不兼容,并且 credentialless 为 false,则使用 response、"navigation"、parentPolicyreport only reporting endpoint、"reporting",以及 target容器文档相关设置 对象排队一个 cross-origin embedder policy inheritance violation

  4. 如果 parentPolicy兼容跨源 隔离,或 responsePolicy兼容跨源 隔离credentialless 为 true, 则返回 true。

  5. 使用 response、"navigation"、parentPolicyreporting endpoint、"enforce",以及 target容器文档相关设置 对象排队一个 cross-origin embedder policy inheritance violation

  6. 返回 false。

6.1.8. 自动填充

在 "Credentialless iframe" 章节中。定义 web 浏览器应如何配置 其自动填充功能。

自动填充与无凭据 iframe:用户代理 有时 具有帮助用户填写表单的功能:例如预填 用户地址、密码或支付信息。当数据既特定于用户又特定于 网站时,用户代理必须禁用 这些功能。

6.1.9. 环境的 partition nonce

在 "Credentialless iframe" 章节中。定义 page credentialless nonce

每个顶级 Window 都有一个关联的 page credentialless nonce。它是一个不可变的 nonce("number used once")。

environment 对象添加 partition nonce 属性。

一个 partition nonce

一个标识符或 null。它用于进一步区分和隔离 环境。除此之外,它对于无凭据 Window 是非 null 的

6.1.9.1. 用于导航

process a navigate fetch 中,添加步骤:

  1. 如果 credentialless 为 true,则令 partitionNoncebrowsingContext顶级浏览上下文page credentialless nonce,否则为 null。

partitionNonce 稍后用于创建 Environment。修改 步骤 13.3.4:

13.3.4. 将 requestreserved client 设置为一个新的 environment,其 id 是唯一 opaque string,target browsing contextbrowsingContextcreation URLcurrentURLtop-level creation URLtopLevelCreationURLtop-level origintopLevelOriginpartition noncepartitionNonce
.
6.1.9.2. 用于 Window

initialize the document object 中,添加步骤 6.9:

6.9. 如果 navigationParamscredentialless 为 true,则令 partitionNoncebrowsingContext顶级浏览 上下文page credentialless nonce,否则为 null。

然后,将其贯通以在步骤 6.10 中创建 Environment

6.10 使用 creationURLrealm execution contextnavigationParamsreserved environmenttopLevelCreationURLtopLevelOrigin以及 partitionNonce设置 window environment settings object

partitionNonce 以这种方式传递给 set up a window environment settings object

设置 window environment settings object,给定 URL creationURLJavaScript 执行上下文 execution context、null 或一个 environment reservedEnvironmentURL topLevelCreationURLorigin topLevelOrigin,以及标识符 partitionNonce, 运行以下步骤:

它在步骤 6 中使用。

  1. settings objectcreation URL 设置为 creationURL,将 settings objecttop-level creation URL 设置为 topLevelCreationURL,将 settings objecttop-level origin 设置为 topLevelOrigin并将 settings objectpartition nonce 设置为 partitionNonce

6.1.9.3. 用于 Worker

script settings for workers 算法中,添加步骤 8:

  1. settings objectpartition nonce 设置为 outside settingspartition nonce

6.1.9.4. 用于 Worklet

set up a worklet environment settings object 算法中,修改 步骤 7:

  1. settingsObjectid 设置为新的 unique opaque string,将 creation URL 设置为 inheritedAPIBaseURL,将 top-level creation URL 设置为 null, 将 top-level origin 设置为 outsideSettingstop-level originpartition nonce 设置为 outsideSettingspartition nonce,将 target browsing context 设置为 null, 并将 active service worker 设置为 null。

6.2. 与 Fetch 集成

注: 这对应于以下 HTML 规范更改:whatwg/fetch/pull/1416
合并后,本节将过时。

6.2.1. 贯通 partition-nonce

environmentpartition nonce 加入 network partition key。 进行以下更改:

network partition key 是由以下项组成的元组:

要在给定一个 environment environment确定 network partition key, 运行以下步骤:

  1. topLevelOriginenvironmenttop-level origin

  2. 如果 topLevelOrigin 为 null,则将 topLevelOrigin 设置为 environmenttop-level creation URL

  3. 断言:topLevelOrigin 是一个

  4. topLevelSite 为在给定 topLevelOrigin获得站点的结果。

  5. secondKey 为 null 或一个实现定义值。

    第二个键有意保持一点含糊,因为更细节的问题仍在演进中。 见 issue #1035

  6. nonceenvironmentpartition nonce

  7. 返回 (topLevelSite, secondKey, nonce)。

6.3. 与 CHIPS 集成

本节定义了一个针对 [CHIPS] 的 monkey-patch,后者本身是 针对 [COOKIES] 的 monkey-patch。

注 / 摘要:Cookies Having Independent Partitioned State(CHIPS)引入 cookie 的 partition key。为实现无凭据 iframe,当 environmentpartition nonce 被定义时:
  1. 即使没有 "Partitioned" cookie 属性, "partition-key" 也会被定义,并包含:(top-level-site, partition-nonce)。

  2. 不要求 __Host- 前缀。

  3. environment 只能访问其 "partition-key" 被 定义的 cookie。

修改 [CHIPS] 章节:https://github.com/WICG/CHIPS/blob/main/README.md#algorithm

下面是浏览器可用于解析 cookie 行的算法。 该算法可以添加到 RFC6265bis 的第 5.3 节

  1. 令 "partition-key" 为 null。

  2. 如果 如果 environmentpartition nonce 被定义,或某个 attribute-name 以大小写不敏感的方式匹配字符串 "Partitioned",则:

    1. siteenvironmenttop-level originsite

    2. 如果 site 位于 First-Party Set 中,则将 site 设置为 "https://" 与该 site 的集合的 "owner domain" 的拼接。

    3. nonceenvironmentpartition nonce

    4. partition-key 设置为 元组 (site, nonce)

  3. 向 cookie-attribute-list 追加一个属性,其 attribute-name 为 "PartitionKey",attribute-value 为 partition-key

下面是存储 Partitioned cookie 的算法。这些步骤可以 在用户代理处理 cookie 的 __Host- 前缀之后添加到 RFC6265bis 的第 5.4 节

  1. 如果 cookie-attribute-list 包含一个 attribute-name 为 "PartitionKey" 的属性,且 attribute-value 为 null,或 一个元组 (site, nonce),其中 nonce 非 null,则 跳过以下步骤,并将 cookie 插入 cookie store。

  2. 如果 cookie-name 不是以字符串 "__Host-" 的大小写敏感匹配开头,则中止以下步骤并完全忽略该 cookie。

  3. 如果 cookie 行还包含 [SameParty attribute](https://github.com/cfredric/sameparty)(如何将 SameParty 属性加载到 cookie-attribute-list 中的确切语义待定), 则中止以下步骤并完全忽略该 cookie。

  4. 将 cookie 的 partition-key 设置为 attribute-list 中 attribute-name 为 "PartitionKey" 的元素的 attribute-value。

下面是将 Partitioned cookie 附加到请求的算法。这些 步骤可以在第 5.5 节中描述的算法的第一步之后添加。

对于 cookie-list 中的每个 cookie,执行以下操作:

  1. environment 为发起请求的 environment

  2. 如果 cookie 的 partition-key 为 null,environmentpartition nonce 为 null,则跳过 此步骤的以下部分。

  3. request-top-siteenvironmenttop-level originsite

  4. request-partition-nonceenvironmentpartition nonce

  5. 如果 request-top-site 位于 First-Party Set 中,则将 request-top-site 设置为 "https://" 与 request-top-site 的集合的 "owner domain" 的拼接。

  6. request-partition-key 为元组 (request-top-site, request-partition-nonce)。

  7. 如果 cookie 的 partition-key 与 request-partition-key 不完全匹配,则 从 cookie-list 中移除该 cookie。

6.4. 与 storage-partitioning 集成

[StoragePartition]链接)工作项中。大多数 存储 API 将由一个附加键进行键控:顶级站点。

为实现无凭据 iframe,应添加另一个键,并将其定义为 environmentpartition nonce

nonce
environmentpartition nonce

6.5. 与 storage 集成

注: 这对应于以下 [STORAGE] 规范更改:whatwg/storage/pull/139
合并后,本节将过时。

6.5.1. storage-key

environmentpartition nonce 作为附加键加入 storage key

storage key 是一个由以下项组成的元组

要在给定 environment environment 的情况下为非存储用途获得 storage key, 运行以下步骤:

7. 安全考量

7.1. 威胁模型

由于无凭据 iframe 可以嵌入在 crossOriginIsolated 上下文中, 在没有 Out-of-Process-Iframes 的浏览器中,我们必须考虑其 embedder 可以执行 [Spectre] 攻击来读取任何无凭据 iframe 资源,包括 HTML。受害者是加载在 无凭据 iframe 内的文档,其他文档则是攻击者。

我们应对此威胁的方法不是阻止攻击发生,而是 避免加载个性化数据,使攻击者只能访问公开 可用的数据。

为此,我们考虑各种可能的攻击:

7.2. 现有凭据的使用

最危险的攻击也是最直接的攻击。攻击者嵌入 一个无凭据 iframe,其中包含用户已有凭据的资源。 攻击者随后读取 iframe 内的个性化资源,而这些资源 不是公共数据。

缓解:

无凭据 iframe 无权访问其源已存储的现有凭据。 这包括 cookie。这也包括该源共享存储中的任何数据, 因为它可能是使用凭据获取的,因此是个性化的。 无凭据 iframe 从空白状态开始,以防止攻击者使用现有凭据加载 资源。

7.3. 新凭据的使用

在此攻击中,攻击者嵌入一个无凭据 iframe。如上所述, 就凭据和共享存储而言,无凭据 iframe 从空白状态开始。 不过,无凭据 iframe 可以注册新凭据,并 使用这些凭据请求个性化资源。攻击者随后可以读取这些资源。 实际上,我们可以将此场景分为两种。第一种是使用 存储状态所必需的凭据,以使 iframe 站点工作,但这些凭据并非 特定于某个用户。这种情况没有问题,因为它是公开可访问的 数据。第二种是由用户个性化的状态,它会在用户登录无凭据 iframe 后获取。

最后,还有一个问题是此类凭据应持续多久, 以及它们应如何在无凭据 iframe 之间共享。例如,有人可能 设想,用户访问一个合法页面,其中有一个无凭据 iframe A,用户在其中 登录。随后用户访问一个攻击者页面,其中有一个同源 A 的无凭据 iframe。 如果用户仍登录在 A 中,攻击者页面就可能窃取 来自个性化子资源的数据。

缓解:

如果用户直接在 iframe 中输入其凭据以登录, 他们就是登录到 iframe 中,而该页面的地址栏中显示的是不同 URL。 这类似于钓鱼攻击,无论从攻击发生所需的用户操作还是结果来看都是如此。 这种情况不应需要额外缓解。

当用户使用弹出窗口驱动的 OAuth 流程(或即将推出的 WebID API)时, 从用户角度理解这种情况会更困难。为防止 这种情况发生,我们限制 iframe 打开弹出窗口的能力(例如,所有 弹出窗口都以设置了 no-opener 的方式打开),并在 WebID API 发布时限制其访问。

就凭据的生命周期和共享而言,它们绑定到 无凭据 iframe 的生命周期。因此,如果某个页面创建无凭据 iframe, 无凭据 iframe 子树中的文档会获得干净的凭据和共享 存储状态。子树中的文档可以创建凭据。它们可以在 彼此之间共享这些凭据(只要遵守同源策略),并且只能 在彼此之间共享。因此,如果同时打开两个页面,且其中有两个同源的无凭据 iframe,这些无凭据 iframe 不能共享其 凭据。一旦无凭据 iframe 被销毁,在其子树中创建的凭据 应不再可访问。这确保我们尽可能保留 无凭据 iframe 的功能,同时最大限度地降低意外泄漏数据的风险。

7.4. 基于网络位置的个性化资源

这是前一种攻击的变体,其中用户嵌入一个 iframe, 其私有子资源因用户的网络位置而只允许该用户访问。 例如,在用户私有网络上找到的资源,或基于用户 IP 地址个性化的资源。

缓解:

我们计划通过部署 Private Network Access 限制来处理私有网络情况。在 Private Network Access 限制引入的 CORS 预检期间, 服务器将能够通过检查 Sec-Fetch-COEP 标头,确认其资源将被渲染在 无凭据 iframe 上下文中。请注意,只有启用 HTTPS 的 本地网络文档才可能被暴露(因为 MIX 应阻止启用 COI 的页面加载 HTTP 资源)。 这不是强缓解措施,但对常见 IoT 设备之类的东西会有意义。 其他基于 IP 地址个性化资源的情况可以说已经是一个 安全脚枪。我们认为,与在更多请求上不使用凭据的优势相比, 那里的风险增加是可以接受的。

7.5. 用户输入的捕获

在此攻击中,攻击者嵌入一个可以接收用户 输入的无凭据 iframe。然后读取用户输入。

缓解:

这不属于无凭据 iframe 的范围。攻击者已经可以 发起钓鱼攻击:使用公开可用的资源构造假页面, 并诱骗用户输入数据。此攻击是等价的, 因为导航栏中向用户显示的 URL 仍然是攻击者的 URL。

7.6. 无凭据 iframe 使用侧信道对自身进行个性化

无凭据 iframe 可以使用侧信道(例如 broadcast channels、 postMessage)尝试在缺少 凭据的情况下获得某种形式的个性化。随后 embedder 可读取这些个性化资源。

缓解:

取决于上面强调的机制是否是个性化资源的常见方式, 这可能不在范围内。我们想要防御的是不知情的网站被其 embedder 嵌入并攻击以窃取用户数据。如果无凭据 iframe 执意逃离 无凭据 iframe 的约束来对自身进行个性化, 那么可以说它理解自己被加载的上下文和风险,并接受这些风险。 只要我们的安全模型在无凭据 iframe 之外足够安全, 个性化无论如何都只会影响与该 iframe 同源的资源。 对 framed document 而言,跨源资源仍将是 未个性化的,从安全角度看,这等价于 COEP:credentiallesss。

8. 隐私考量

此 API 带来的主要隐私威胁,是通过类似 [Spectre] 的侧信道攻击发生数据泄漏的风险。 如上文威胁模型中详述, 我们认为 该 API 针对 [Spectre] 攻击提供了有意义的防御, 因此不会构成 隐私风险。

9. 自审问卷

参见 [SecurityPrivacyQuestionnaire]链接

9.1. 此功能可能向网站或其他方暴露哪些信息,且这种暴露出于什么 目的而必要?

window.credentialless 方法暴露一个文档是否加载在 无凭据 iframe 中,从而允许文档根据 现有凭据或已存储资源的可用性来改变其行为。

9.2. 你的规范中的功能是否暴露了启用其预期用途所需的最少量信息?

是。唯一暴露的是文档是否嵌入在 无凭据 iframe 中。

9.3. 你的规范中的功能如何处理个人信息、 可识别个人身份的信息(PII),或从中派生的信息?

该功能不处理 PII。

9.4. 你的规范中的功能如何处理敏感 信息?

该功能不处理敏感信息。

9.5. 你的规范中的功能是否为源引入了会跨浏览会话持久存在的新状态?

否,该功能不会为源引入新状态。

9.6. 你的规范中的功能是否向源暴露有关底层平台的信息?

否,该功能无论底层平台如何都表现相同。

9.7. 本规范是否允许源向底层 平台发送数据?

否,此功能不会改变源允许向底层平台发送的数据。

9.8. 本规范中的功能是否允许源访问用户 设备上的传感器?

否,该功能对传感器访问没有影响。

9.9. 本规范中的功能是否启用新的脚本执行/加载 机制?

否,该功能不会启用新的脚本执行/加载。

9.10. 本规范中的功能是否允许源访问其他 设备?

否,该功能严格限于一个设备。

9.11. 本规范中的功能是否允许源对 用户代理的原生 UI 进行某种程度的控制?

否,该功能对 UI 没有影响。

9.12. 本规范中的功能会创建或向 web 暴露哪些临时标识符?

不会创建临时标识符。

9.13. 本规范如何区分第一方与 第三方上下文中的行为?

第一方和第三方嵌入 无凭据 iframe 的能力没有区别。这是由于 COEP 的递归性质。 要在 frame 中部署 COEP,所有子 frame 都需要先部署 COEP。 由于这是帮助部署 COEP 的机制,我们希望为第三方 iframe 提供选项,使其能够通过把自己的第三方内容作为无凭据 iframe 嵌入来简化自己的 COEP 部署。

9.14. 本规范中的功能在浏览器的 私密浏览或无痕模式上下文中如何工作?

与常规模式没有区别。

9.15. 本规范是否同时具有“安全考量”和“隐私 考量”章节?

是:

9.16. 你的规范中的功能是否允许源降低默认安全 保护?

此功能对安全上下文和同源策略没有影响。它确实 允许使用目前被门控在启用 COOP 和 COEP 之后的功能。 不过,它对文档施加限制以确保安全。

9.17. 你的功能如何处理非“完全活跃”的文档?

无凭据 iframe 只影响 iframe 内的文档。一般 假设是后退/前进 缓存功能仅针对主 frame 导航实现。在此假设下,没有什么特殊事情要做。

在子 frame 级别实现后退/前进缓存的假想 web 浏览器, 必须认真考虑当 iframe 的 "credentialless" 属性已更改时, 恢复其中的文档会发生什么。例如, 它们可以阻止后退/前进缓存恢复该文档。

索引

由本 规范定义的术语

由 引用定义的术语

参考文献

规范性参考文献

[CHIPS]
Dylan Cutler; Kaustubha Govind. 具有独立 分区状态的 Cookie(CHIPS). URL: https://github.com/WICG/CHIPS
[COOKIES]
Mike West; John Wilander. Cookie:HTTP 状态 管理机制. URL: https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-07
[CSS-COLOR-3]
Tantek Çelik; Chris Lilley; David Baron. CSS Color Module Level 3. URL: https://drafts.csswg.org/css-color-3/
[DOM]
Anne van Kesteren. DOM 标准. 现行标准. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript 语言规范. URL: https://tc39.es/ecma262/multipage/
[FETCH]
Anne van Kesteren. Fetch 标准. 现行 标准. URL: https://fetch.spec.whatwg.org/
[HTML]
Anne van Kesteren; et al. HTML 标准. 现行标准. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 标准. 现行标准. URL: https://infra.spec.whatwg.org/
[STORAGE]
Storage. URL: https://storage.spec.whatwg.org/
[StoragePartition]
客户端存储 分区. URL: https://privacycg.github.io/storage-partitioning/
[URL]
Anne van Kesteren. URL 标准. 现行标准. URL: https://url.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL 标准. 现行 标准. URL: https://webidl.spec.whatwg.org/

资料性参考文献

[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. 安全与隐私 自审问卷. URL: https://www.w3.org/TR/security-privacy-questionnaire/
[Spectre]
Paul Kocher; et al. Spectre 攻击:利用 推测执行. URL: https://spectreattack.com/spectre.pdf
[WEB-SQL]
Ian Hickson. Web SQL Database. 2010 年 11 月 18 日. NOTE. URL: https://www.w3.org/TR/webdatabase/
[WebStorage]
Ian Hickson. Web Storage(第二版). URL: https://w3c.github.io/webstorage/
[WhyCoopCoep]
Eiji Kitamura; Demenic Denicola. 为什么强大功能需要“跨源 隔离”. URL: https://web.dev/why-coop-coep/

IDL 索引

partial interface HTMLIFrameElement {
  attribute boolean credentialless;
};

partial interface Window {
  readonly attribute boolean credentialless;
};