1. 引言
本节为非规范性内容。
当用户通过安全通道(例如 HTTPS)成功加载来自 example.com 的网页时,用户可以获得在用户代理与 example.com
之间传输的数据未被中间实体窃听或篡改的保证。然而,如果网页通过不安全的连接加载了脚本或图片等子资源,这一保证就会被削弱。例如,不安全加载的脚本可能允许攻击者代表用户读取或修改数据。不安全加载的图片则可能允许攻击者向用户传递错误信息(如伪造的股票图表)、修改客户端状态(如设置
cookie),或诱导用户采取非预期操作(如更改按钮标签)。这些请求被称为混合内容。
本规范详细说明了用户代理如何通过阻止某些类型的混合内容,并在某些场景下采取更严格的行为,来降低这些风险。
然而,本规范的早期版本并未完全保护用户数据的机密性和完整性。不安全的内容(如图片、音频和视频)目前仍可在安全环境中被默认加载。安全页面甚至可以发起逃离用户代理沙箱的不安全下载。
此外,当加载混合内容时,用户并没有明确的安全指示。当网页加载混合内容时,浏览器仅显示“中间”安全指示(如移除锁形图标),无法让用户清楚地判断是否应该信任该页面。这种用户体验也未能充分激励开发者避免混合内容,因为网页加载混合内容的现象依然普遍。如果全部阻止混合内容,将为用户提供更简单的认知模型——网页要么是通过安全通道加载的,要么不是——并鼓励开发者以安全方式加载网页所需的混合内容。
因此,本规范进行了更新,以在尽量减少兼容性问题的同时,为用户提供更好的安全与隐私保障以及更佳的安全体验。本规范不再建议浏览器简单地严格阻止所有混合内容,而是建议采用 混合内容自动升级:
-
用户代理当前尚未阻止的混合内容应自动升级为通过安全通道传输。
-
如果请求无法自动升级,则会被阻止。
自动升级可避免在安全网页中加载不安全资源,同时最大限度减少开发者为避免出错所需的工作量。
本规范仅建议对当前未被默认阻止的混合内容子资源类型进行自动升级,不建议对已被默认阻止的内容类型进行自动升级。这样做是为了尽量减少对网页可见性的影响;我们只希望在有助于实现默认阻止所有混合内容目标时才自动升级内容。
本规范还明确引入了 混合下载 的概念。混合下载指的是由安全环境发起、但通过不安全连接下载的资源,且用户代理将其作为下载处理。用户代理应阻止混合下载,因为它们可能会逃离用户代理的沙箱(如可执行文件),或包含敏感信息(如银行账单)。这尤其具有误导性,因为用户代理通常会在发起和完成混合下载时,向用户显示他们正处于安全页面。
2. 关键概念与术语
- 混合内容
-
当一个 请求 的 URL 不是 潜在可信的 URL [SECURE-CONTEXTS],且负责加载它的上下文禁止混合安全上下文(有关后者的规范性定义详见
§ 4.3 设置是否禁止混合安全上下文?),则该请求为混合内容。
当一个 响应 是 未经认证的响应,且负责加载它的上下文要求禁止混合安全上下文时,该响应为混合内容。
注:"混合内容"最初定义于 第5.3节,见 [WSC-UI]。本文档对最初定义进行了更新。
注: [XML] 也定义了一个无关的“混合内容”概念。虽然有潜在混淆,但考虑到该术语在安全领域被用户代理广泛采用超过十年,实际混淆风险较低。
- 未经认证的响应
- 我们可以 事后 知道一个 响应(response)是未经认证的,如果 response 的 URL 不是 潜在可信的 URL。
- 嵌入文档
- 给定一个
DocumentA,A 的嵌入文档是 A 的浏览上下文的容器文档 [HTML]。 - 混合下载
- 混合下载指的是由安全环境发起、但通过不安全连接下载的资源,且用户代理将其作为下载处理。
先验认证的URL 等同于 潜在可信的 URL [SECURE-CONTEXTS]。
3. 内容类别
在理想情况下,每个用户代理都应当无例外地阻止所有混合内容。然而,在当今的互联网环境下,这样做并不现实;用户代理需要采取更细致的限制措施,以避免大量网站的用户体验受损。
基于这一考虑,我们将混合内容分为两类:§ 3.1 可升级内容 和 § 3.2 可阻止内容。
3.1. 可升级内容
可升级内容在本规范早期版本中曾被称为 可选阻止 内容。
当作为混合内容允许其使用的风险小于阻止其使用可能导致大范围网站功能故障的风险时,该混合内容被定义为可升级。这通常是因为该类型资源的混合使用非常普遍,且资源本身风险较低。被划为可升级内容并不意味着它们是安全的,只是相较于其他类型的资源,它们的危害性没有那么巨大。例如,图像和图标常常是应用界面的核心元素。如果攻击者调换了“删除邮件”和“回复”图标,将对用户造成实际影响。
此类别包括:
-
注:这对应于大多数通过
img加载的图像 (包括作为图像加载的 SVG 文档,因为这些文档被禁止执行脚本或获取子资源)以及 CSS (background-image、border-image 等)加载的图像。它不包括img元素中使用 srcset 或 picture的情况。 -
目标为 "
video" 的请求。 -
目标为 "
audio" 的请求。
我们在§ 4.4
是否应将请求拦截为混合内容?进一步限制了该类别,对所有启用 CORS 的请求强制失败。这意味着,例如,带有 <img crossorigin ...>
的混合内容图片将被阻止。这很好地体现了只有在内容无法被完全阻止时才归入该类别的一般原则。工作组计划随着时间推移将更多内容划分为可阻止子集。
3.2. 可阻止内容
所有不属于上述可升级类型的混合内容,都被归为可阻止类型。典型例子包括脚本、插件数据、通过 XMLHttpRequest
发起的数据请求等。
注: 导航请求 可能指向顶级浏览上下文,这些不被认为是混合内容。详情请参见§ 4.4 是否应将请求拦截为混合内容?。
注: 插件发起的请求也属于可阻止类型。但我们认识到,用户代理并不总能拦截这些请求。例如 NPAPI 插件通常拥有直接的网络访问权限,可以完全绕过用户代理。我们建议用户代理在可能时阻止这些请求,同时建议插件厂商自行实现混合内容检查,以降低本规范所述风险。
4. 算法
4.1. 如有需要,将混合内容 请求 升级为 潜在可信的URL
注: Fetch 规范将挂钩此算法以将可升级的混合内容升级至 HTTPS。
给定一个 请求 request,此算法会在请求被认定为可升级混合内容时,按下述算法重写其 URL:
-
若满足以下任一条件,则直接返回,不修改 request:
- request 的 URL 是 潜在可信的URL。
- request 的 URL 的 主机为 IP 地址。
- § 4.3 设置是否禁止混合安全上下文? 应用于 request 的
client 时返回“
不限制混合安全上下文”。 - request 的 目标类型(destination) 不是
"
image"、"audio" 或 "video"。 -
request 的 目标类型 为 "
image" 且 request 的 initiator 为 "imageset"。注: 出于历史原因,"
imageset" 不会被升级。在某些类型的混合内容被升级前,规范将混合内容分为可阻止和可选阻止,后者只针对不常见的内容类型。"imageset" 属于前者,因此升级功能并未覆盖此前定义为可阻止的内容。
-
如果 request 的 URL 的 协议(scheme) 为
http, 则将其 URL 的 协议 设置为https,然后返回。注: 按 [url] 规范,不修改端口号,因为当协议为
http时端口会被设为 null,协议变为https后将默认解释为 443。
4.2. 对先前算法的修改
注: 本节包括对规范早期版本算法的修改——忽略可选阻止与可阻止混合内容的区分,因为所有可选阻止混合内容现在都将被自动升级。
4.3. settings 是否禁止混合安全上下文?
文档和 worker 都有 环境设置对象,可通过以下算法判断是否限制混合内容。该算法返回
“禁止混合安全上下文”或“不禁止混合安全上下文”:
给定一个 环境设置对象 (settings):
-
如果 settings 的 来源(origin) 是 潜在可信来源,则返回 “
禁止混合安全上下文”。 -
如果 settings 的 全局对象(global object) 为
window, 则:-
对于每个 可导航对象(navigable) navigable,位于 document 的 祖先 navigables 中:
-
如果 navigable 的 活动文档的 来源(origin) 是 潜在可信来源, 则返回 “
禁止混合安全上下文”。
-
-
返回 “
不限制混合安全上下文”。
4.4. 是否应将 请求 拦截为混合内容?
注: Fetch 规范挂钩此算法判断请求是否应被完全阻止(例如,请求为可阻止内容,并且可假定其不会通过安全连接加载)。
给定一个 请求 request,用户代理根据以下算法判断 请求 request 是否应继续:
-
若满足以下任一条件,则返回 允许:
- § 4.3 设置是否禁止混合安全上下文? 应用于
request 的 client 时返回“
不限制混合安全上下文”。 - request 的 URL 是 潜在可信的URL。
- 用户代理被指示允许混合内容(见 § 7.2 用户控制)。
-
request 的 目标类型(destination)为
"
document",且 request 的 目标浏览上下文无 父级浏览上下文。注: 我们将顶级导航排除在混合内容检查之外,但用户代理可以选择对不安全表单提交强制混合内容检查(见§ 7.1 表单提交)。
- § 4.3 设置是否禁止混合安全上下文? 应用于
request 的 client 时返回“
- 返回 阻止。
4.5. 是否应将 请求 的 响应 拦截为混合内容?
注: 即使请求通过,我们仍可能基于响应连接状态(例如请求为可阻止但连接为 未经认证),决定是否阻止响应;同时需确保 Service Worker 不会为 可阻止请求意外返回 未经认证响应。本算法用于做出此判断。
给定 请求 request 和 响应 response,用户代理根据以下算法判断应返回哪种响应:
-
若满足以下任一条件,则返回 允许:
- § 4.3 设置是否禁止混合安全上下文? 应用于
request 的 client 时返回“
不限制混合内容”。 - response 的 url 是 潜在可信的URL。
- 用户代理被指示允许混合内容(见 § 7.2 用户控制)。
-
request 的 目标类型(destination)为
"
document",且 request 的 目标浏览上下文无 父级浏览上下文。注: 我们将顶级导航排除在混合内容检查之外,但用户代理可以选择对不安全表单提交强制混合内容检查(见§ 7.1 表单提交)。
- § 4.3 设置是否禁止混合安全上下文? 应用于
request 的 client 时返回“
- 返回 阻止。
5. 集成
5.1. 对 Fetch 的修改
Fetch § 4.1 Main fetch 应修改为在第3步和第4步之间调用 § 4.1 如有需要,将混合内容请求升级为潜在可信的URL,即,在应用混合内容阻止机制之前,将可升级的混合内容自动升级为 HTTPS。
5.2. 对 HTML 的修改
处理导航响应应作如下修改:第3步在 source 的 活动文档的 URL 是 潜在可信的URL且 response 的 URL 列表中存在任何不是 潜在可信的URL 时,应中止下载并返回。
类似地,下载超链接的算法应做如下修改:第6.2步应改为:若 subject 的 节点文档的 URL 是 潜在可信的URL,且 response 的 URL 列表中存在任何不是 潜在可信的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,
并允许用户中止提交。如果用户代理会对
form
元素
提交到非潜在可信 URL时发出警告,那么如果在提交时,
form
元素的 action 重定向到
非潜在可信 URL,从而暴露
form
信息,则它也应该发出警告并允许用户
中止提交。
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 帮助规范保持聚焦、简洁和合理。