混合内容

W3C 候选推荐草案

关于本文档的更多信息
此版本:
https://www.w3.org/TR/2023/CRD-mixed-content-20230223/
最新发布版本:
https://www.w3.org/TR/mixed-content/
编辑草案:
https://w3c.github.io/webappsec-mixed-content/
先前版本:
历史:
https://www.w3.org/standards/history/mixed-content
反馈:
public-webappsec@w3.org 邮件主题请写为 “[mixed-content] …消息主题…” (存档)
GitHub:
提交问题 (开放问题)
实现报告:
https://wpt.fyi/results/mixed-content
编辑者:
(Google Inc.)
(Google Inc.)
(Google Inc.)
参与:
提交问题 (开放问题)

摘要

本规范描述了用户代理在加密和经过认证的文档中,如何处理通过未加密或未经认证的连接获取的内容。

本文件状态

本节描述了本文档在发布时的状态。当前W3C出版物列表和本技术报告的最新修订版可在 W3C技术报告索引 https://www.w3.org/TR/ 查询。

本文档由 Web应用安全工作组 按照 推荐流程 作为候选推荐草案发布。本文档计划成为W3C推荐标准。

(存档) 公共邮件列表 public-webappsec@w3.org (参见说明)为本规范讨论的首选渠道。发送电子邮件时, 主题请带上“mixed-content”,建议格式:“[mixed-content] …评论摘要…

作为候选推荐发布并不代表 W3C 及其成员的认可。候选推荐草案整合了工作组打算在后续快照中包含的前一候选推荐的修改。本文件为草稿,随时可能更新、替换或废弃。引用本文件仅应视为工作进展,不应作为正式依据。

本文档进入拟推荐阶段的准入条件是至少有两个独立且互操作的用户代理实现了本规范的所有特性,并通过工作组制定的测试套件中的用户代理测试。工作组将准备实现报告以跟踪进展。

本文档由遵循W3C专利政策 的工作组编写。W3C维护了与本组交付物相关的 公开专利披露列表; 该页面也包含披露专利的说明。个人如获知包含 必要权利要求 的专利,应依 W3C专利政策第6节披露相关信息。

本文档受 2021年11月2日W3C流程文档 管辖。

1. 引言

本节为非规范性内容。

当用户通过安全通道(例如 HTTPS)成功加载来自 example.com 的网页时,用户可以获得在用户代理与 example.com 之间传输的数据未被中间实体窃听或篡改的保证。然而,如果网页通过不安全的连接加载了脚本或图片等子资源,这一保证就会被削弱。例如,不安全加载的脚本可能允许攻击者代表用户读取或修改数据。不安全加载的图片则可能允许攻击者向用户传递错误信息(如伪造的股票图表)、修改客户端状态(如设置 cookie),或诱导用户采取非预期操作(如更改按钮标签)。这些请求被称为混合内容。

本规范详细说明了用户代理如何通过阻止某些类型的混合内容,并在某些场景下采取更严格的行为,来降低这些风险。

然而,本规范的早期版本并未完全保护用户数据的机密性和完整性。不安全的内容(如图片、音频和视频)目前仍可在安全环境中被默认加载。安全页面甚至可以发起逃离用户代理沙箱的不安全下载。

此外,当加载混合内容时,用户并没有明确的安全指示。当网页加载混合内容时,浏览器仅显示“中间”安全指示(如移除锁形图标),无法让用户清楚地判断是否应该信任该页面。这种用户体验也未能充分激励开发者避免混合内容,因为网页加载混合内容的现象依然普遍。如果全部阻止混合内容,将为用户提供更简单的认知模型——网页要么是通过安全通道加载的,要么不是——并鼓励开发者以安全方式加载网页所需的混合内容。

因此,本规范进行了更新,以在尽量减少兼容性问题的同时,为用户提供更好的安全与隐私保障以及更佳的安全体验。本规范不再建议浏览器简单地严格阻止所有混合内容,而是建议采用 混合内容自动升级

自动升级可避免在安全网页中加载不安全资源,同时最大限度减少开发者为避免出错所需的工作量。

本规范仅建议对当前未被默认阻止的混合内容子资源类型进行自动升级,不建议对已被默认阻止的内容类型进行自动升级。这样做是为了尽量减少对网页可见性的影响;我们只希望在有助于实现默认阻止所有混合内容目标时才自动升级内容。

本规范还明确引入了 混合下载 的概念。混合下载指的是由安全环境发起、但通过不安全连接下载的资源,且用户代理将其作为下载处理。用户代理应阻止混合下载,因为它们可能会逃离用户代理的沙箱(如可执行文件),或包含敏感信息(如银行账单)。这尤其具有误导性,因为用户代理通常会在发起和完成混合下载时,向用户显示他们正处于安全页面。

2. 关键概念与术语

混合内容
当一个 请求URL 不是 潜在可信的 URL [SECURE-CONTEXTS]负责加载它的上下文禁止混合安全上下文(有关后者的规范性定义详见 § 4.3 设置是否禁止混合安全上下文?),则该请求为混合内容

当一个 响应未经认证的响应负责加载它的上下文要求禁止混合安全上下文时,该响应为混合内容

在限制混合内容的上下文中(例如 https://secure.example.com/):
  1. 请求脚本 http://example.com/script.js混合内容。由于脚本 请求属于可阻止类型,用户代理将返回网络错误,而不会加载该资源。

  2. 请求图片 http://example.com/image.png混合内容。由于图片 请求属于可升级类型,用户代理可能会将 URL 重写为 https://example.com/image.png,否则将阻止加载。

注:"混合内容"最初定义于 第5.3节,见 [WSC-UI]。本文档对最初定义进行了更新。

注: [XML] 也定义了一个无关的“混合内容”概念。虽然有潜在混淆,但考虑到该术语在安全领域被用户代理广泛采用超过十年,实际混淆风险较低。

未经认证的响应
我们可以 事后 知道一个 响应response)是未经认证的,如果 responseURL 不是 潜在可信的 URL
嵌入文档
给定一个 Document AA嵌入文档A浏览上下文容器文档 [HTML]
混合下载
混合下载指的是由安全环境发起、但通过不安全连接下载的资源,且用户代理将其作为下载处理。

先验认证的URL 等同于 潜在可信的 URL [SECURE-CONTEXTS]

3. 内容类别

在理想情况下,每个用户代理都应当无例外地阻止所有混合内容。然而,在当今的互联网环境下,这样做并不现实;用户代理需要采取更细致的限制措施,以避免大量网站的用户体验受损。

基于这一考虑,我们将混合内容分为两类:§ 3.1 可升级内容§ 3.2 可阻止内容

3.1. 可升级内容

可升级内容在本规范早期版本中曾被称为 可选阻止 内容。

当作为混合内容允许其使用的风险小于阻止其使用可能导致大范围网站功能故障的风险时,该混合内容被定义为可升级。这通常是因为该类型资源的混合使用非常普遍,且资源本身风险较低。被划为可升级内容并不意味着它们是安全的,只是相较于其他类型的资源,它们的危害性没有那么巨大。例如,图像和图标常常是应用界面的核心元素。如果攻击者调换了“删除邮件”和“回复”图标,将对用户造成实际影响。

此类别包括:

  • 发起者为空字符串且目标类型为 "image" 的请求。

    注: 这对应于大多数通过 img 标签加载的图片(包括作为图片加载的 SVG 文档,因为这些文档被阻止执行脚本或加载子资源)以及 CSS (background-imageborder-image 等)。不包括 img 元素使用 srcset 或 picture 属性的情况。

  • 目标类型为 "video" 的请求。

    注: 这对应于使用 videosource 标签加载的视频。

  • 目标类型为 "audio" 的请求。

    注: 这对应于使用 audiosource 标签加载的音频。

我们在§ 4.4 是否应将请求拦截为混合内容?进一步限制了该类别,对所有启用 CORS 的请求强制失败。这意味着,例如,带有 <img crossorigin ...> 的混合内容图片将被阻止。这很好地体现了只有在内容无法被完全阻止时才归入该类别的一般原则。工作组计划随着时间推移将更多内容划分为可阻止子集。

3.2. 可阻止内容

所有不属于上述可升级类型的混合内容,都被归为可阻止类型。典型例子包括脚本、插件数据、通过 XMLHttpRequest 发起的数据请求等。

注: 导航请求 可能指向顶级浏览上下文,这些不被认为是混合内容。详情请参见§ 4.4 是否应将请求拦截为混合内容?

注: 插件发起的请求也属于可阻止类型。但我们认识到,用户代理并不总能拦截这些请求。例如 NPAPI 插件通常拥有直接的网络访问权限,可以完全绕过用户代理。我们建议用户代理在可能时阻止这些请求,同时建议插件厂商自行实现混合内容检查,以降低本规范所述风险。

4. 算法

4.1. 如有需要,将混合内容 请求 升级为 潜在可信的URL

注: Fetch 规范将挂钩此算法以将可升级的混合内容升级至 HTTPS。

给定一个 请求 request,此算法会在请求被认定为可升级混合内容时,按下述算法重写其 URL

  1. 若满足以下任一条件,则直接返回,不修改 request
    1. requestURL潜在可信的URL
    2. requestURL主机IP 地址
    3. § 4.3 设置是否禁止混合安全上下文? 应用于 requestclient 时返回“不限制混合安全上下文”。
    4. request目标类型(destination) 不是 "image"、"audio" 或 "video"。
    5. request目标类型 为 "image" 且 requestinitiator 为 "imageset"。

      注: 出于历史原因,"imageset" 不会被升级。在某些类型的混合内容被升级前,规范将混合内容分为可阻止和可选阻止,后者只针对不常见的内容类型。"imageset" 属于前者,因此升级功能并未覆盖此前定义为可阻止的内容。

  2. 如果 requestURL协议(scheme)http, 则将其 URL协议 设置为 https,然后返回。

    注:[url] 规范,不修改端口号,因为当协议为 http 时端口会被设为 null,协议变为 https 后将默认解释为 443。

4.2. 对先前算法的修改

注: 本节包括对规范早期版本算法的修改——忽略可选阻止与可阻止混合内容的区分,因为所有可选阻止混合内容现在都将被自动升级。

4.3. settings 是否禁止混合安全上下文?

文档和 worker 都有 环境设置对象,可通过以下算法判断是否限制混合内容。该算法返回 “禁止混合安全上下文”或“不禁止混合安全上下文”:

给定一个 环境设置对象 (settings):

  1. 如果 settings来源(origin)潜在可信来源,则返回 “禁止混合安全上下文”。

  2. 如果 settings全局对象(global object)window, 则:

    1. document 设为 settings全局对象关联文档

    2. 对于每个 可导航对象(navigable) navigable,位于 document祖先 navigables 中:

      1. 如果 navigable活动文档来源(origin)潜在可信来源, 则返回 “禁止混合安全上下文”。

  3. 返回 “不限制混合安全上下文”。

如果文档有 嵌入文档,用户代理需要检查的不仅是文档本身,还要检查其所在的 顶级浏览上下文,因为用户对所加载资源安全状态的预期由此上下文决定。例如:
http://a.com 加载 http://evil.com。该不安全请求会被允许,因为 a.com 并未通过安全连接加载。
https://a.com 加载 http://evil.com。该不安全请求将被阻止,因为 a.com 是通过安全连接加载的。
http://a.com 框架 https://b.com,后者加载 http://evil.com。此时对 evil.com 的不安全请求会被阻止,因为 b.com 是通过安全连接加载的,即使 a.com 不是。
https://a.com 框架一个 data: URL,后者加载 http://evil.com。这种情况下对 evil.com 的不安全请求也会被阻止,因为 a.com 是通过安全连接加载的,即使被框架的 data: URL 在顶级上下文中加载时不会阻止混合内容。

4.4. 是否应将 请求 拦截为混合内容?

注: Fetch 规范挂钩此算法判断请求是否应被完全阻止(例如,请求为可阻止内容,并且可假定其不会通过安全连接加载)。

给定一个 请求 request,用户代理根据以下算法判断 请求 request 是否应继续:

  1. 若满足以下任一条件,则返回 允许
    1. § 4.3 设置是否禁止混合安全上下文? 应用于 requestclient 时返回“不限制混合安全上下文”。
    2. requestURL潜在可信的URL
    3. 用户代理被指示允许混合内容(见 § 7.2 用户控制)。
    4. request目标类型(destination)为 "document",且 request目标浏览上下文父级浏览上下文

      注: 我们将顶级导航排除在混合内容检查之外,但用户代理可以选择对不安全表单提交强制混合内容检查(见§ 7.1 表单提交)。

  2. 返回 阻止

4.5. 是否应将 请求响应 拦截为混合内容?

注: 即使请求通过,我们仍可能基于响应连接状态(例如请求为可阻止但连接为 未经认证),决定是否阻止响应;同时需确保 Service Worker 不会为 可阻止请求意外返回 未经认证响应。本算法用于做出此判断。

给定 请求 request响应 response,用户代理根据以下算法判断应返回哪种响应:

  1. 若满足以下任一条件,则返回 允许
    1. § 4.3 设置是否禁止混合安全上下文? 应用于 requestclient 时返回“不限制混合内容”。
    2. responseurl潜在可信的URL
    3. 用户代理被指示允许混合内容(见 § 7.2 用户控制)。
    4. request目标类型(destination)为 "document",且 request目标浏览上下文父级浏览上下文

      注: 我们将顶级导航排除在混合内容检查之外,但用户代理可以选择对不安全表单提交强制混合内容检查(见§ 7.1 表单提交)。

  2. 返回 阻止

5. 集成

5.1. 对 Fetch 的修改

Fetch § 4.1 Main fetch 应修改为在第3步和第4步之间调用 § 4.1 如有需要,将混合内容请求升级为潜在可信的URL,即,在应用混合内容阻止机制之前,将可升级的混合内容自动升级为 HTTPS。

5.2. 对 HTML 的修改

处理导航响应应作如下修改:第3步在 source活动文档URL潜在可信的URLresponseURL 列表中存在任何不是 潜在可信的URL 时,应中止下载并返回。

类似地,下载超链接的算法应做如下修改:第6.2步应改为:若 subject节点文档URL潜在可信的URL,且 responseURL 列表中存在任何不是 潜在可信的URL (其中 response 为获取 request 的结果),则应返回并中止下载。

注: 下载类资源不会像其他类型混合内容一样被自动升级,因为用户代理在请求资源之前未必知道该资源将会被下载。

注: 资源在用户代理决定是否因连接不安全而中止下载之前就已被下载。因此,即使最终用户代理阻止了下载,敏感信息也有可能被传输到网络。这通常无法避免,因为用户代理往往要等收到最终响应后才知道资源会被下载,但通过阻止资源,用户代理可以促进网站运营者通过安全连接分发下载资源。

6. 废弃内容

6.1. 严格混合内容检查

本规范的早期版本定义了 block-all-mixed-content CSP 指令。该指令现已废弃,因为所有混合内容在无法自动升级时都会被阻止。

注: upgrade-insecure-requests ([upgrade-insecure-requests]) 指令并未废弃,因为它允许开发者升级可阻止内容。本规范仅默认升级可升级内容。

7. 安全与隐私考量

总体而言,自动升级可升级混合内容预期将带来正面的安全和隐私效益,能保护更多用户流量免遭网络窃听和篡改。

通过加载开发者未预期的资源,可能会在网页中引入安全或隐私问题。例如,假设网站引用了 http://www.example.com/image.jpg 的一张无害图片,但 https://www.example.com/image.jpg 出于某种原因被重定向到了跟踪网站。此时浏览器就会在没有开发者和用户明确同意的情况下,引入隐私问题。不过,这种情况被认为极为罕见。通过仅自动升级可升级内容、不自动升级可阻止内容,可以降低风险。可阻止内容可能带来更大风险,比如加载过时且存在漏洞的 JavaScript 库。

7.1. 表单提交

如果 § 4.3 设置是否禁止混合安全上下文? 应用于 Document相关设置对象时返回 限制混合内容,则用户代理可选择在页面存在一个或多个 form 元素,且其 action 属性值不是 潜在可信URL 时,向用户发出警告。

用户代理可选择在提交 form 元素时,若其 action 属性值不是 潜在可信URL 时,向用户发出警告并允许用户中止提交。如果用户代理在提交到非 潜在可信URL 时发出警告,则也应在表单 action 重定向到非潜在可信 URL 时发出警告并允许用户中止提交,以防表单信息泄露。

此外,用户代理可将来自此类 Document 的表单提交视为可阻止请求,即使提交发生在顶级浏览上下文中。

7.2. 用户控制

用户代理可为用户提供能力,允许其在特定页面上覆盖阻止可阻止混合内容的决定。

注: 实际上,用户代理可能无法完全不提供这样的后门。不过,允许混合脚本尤其危险,任何用户代理 确实不应 [RFC6919] 在没有充分说明与风险沟通的情况下向用户呈现此类选项。

用户代理可为用户提供能力,允许其在特定页面上覆盖自动升级可升级混合内容的决定。

用户代理提供的任何此类控制也必须通过辅助技术的可访问性 API 向辅助技术用户开放。

8. 致谢

除了来自 WebAppSec 工作组的宝贵反馈外,Chrome 安全团队在准备本规范过程中也做出了巨大贡献。特别感谢 Chris Palmer、Chris Evans、Ryan Sleevi、Michal Zalewski、Ken Buchanan 和 Tom Sepez 给予的早期反馈。Anne van Kesteren 解释了 Fetch,帮助定义了本规范的接口,并对第二版更新提出了宝贵建议。Brian Smith 帮助规范保持聚焦、简洁和合理。

索引

本规范定义的术语

引用定义的术语

参考文献

规范性引用

[DOM]
Anne van Kesteren. DOM 标准. Living Standard. URL: https://dom.spec.whatwg.org/
[FETCH]
Anne van Kesteren. Fetch 标准. Living Standard. URL: https://fetch.spec.whatwg.org/
[HTML]
Anne van Kesteren 等. HTML 标准. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 标准. Living Standard. URL: https://infra.spec.whatwg.org/
[SECURE-CONTEXTS]
Mike West. 安全上下文(Secure Contexts). 2021年9月18日. CR. URL: https://www.w3.org/TR/secure-contexts/
[URL]
Anne van Kesteren. URL 标准. Living Standard. URL: https://url.spec.whatwg.org/
[XHR]
Anne van Kesteren. XMLHttpRequest 标准. Living Standard. URL: https://xhr.spec.whatwg.org/

资料性引用

[CSS-BACKGROUNDS-3]
Bert Bos; Elika Etemad; Brad Kemper. CSS 背景与边框模块3. 2023年2月14日. CR. URL: https://www.w3.org/TR/css-backgrounds-3/
[RFC6919]
R. Barnes; S. Kent; E. Rescorla. 在RFC中表示需求级别的更多关键词. 2013年4月1日. 实验性. URL: https://www.rfc-editor.org/rfc/rfc6919
[UPGRADE-INSECURE-REQUESTS]
Mike West. 升级不安全请求. 2015年10月8日. CR. URL: https://www.w3.org/TR/upgrade-insecure-requests/
[WSC-UI]
Thomas Roessler; Anil Saldhana. Web 安全上下文:用户界面指南. 2010年8月12日. REC. URL: https://www.w3.org/TR/wsc-ui/
[XML]
Tim Bray 等. 可扩展标记语言(XML)1.0(第五版). 2008年11月26日. REC. URL: https://www.w3.org/TR/xml/