1. 引言
在整个存在期间,Web 已经演进成一个能力越来越强的 应用平台。安全上下文形式化了传输安全,跨源 隔离缓解了侧信道攻击,而浏览器和操作系统 已经尝试了基于选择特定文件和设备的权限界面, 以使访问范围更明确,并更容易被用户理解。这些 进展中的每一项,要么改进了 Web 平台的安全保证,要么引导用户对页面 行为形成更准确的预期,并解锁了可以安全 带到 Web 的新类别能力。
尽管有这些进展,仍然有一些 API 无法安全地 暴露给 Web,因为它们以无法合理解决的方式 违反了 Web 的安全原语,或者无法足够清晰地向 用户解释,使用户能够就是否授予某个站点对 它们的访问权作出知情决定。如果平台无法证明 将某个 API 暴露给特定站点是安全的,那么信任 必须来自外部证明。
关于页面安全性或行为的任何断言,都需要了解该页面的 内容和行为;只有在被担保的代码与正在执行的代码 相同时,证明才有意义。因此,任何 委托信任决策的系统都必须能够验证其正在运行的 代码的完整性——它必须知道该代码与被 委托信任的代码相匹配。
此外,不适合 Web 当前安全模型的能力 可能会给其他 Web 内容带来风险。此风险是 双向的:突破沙箱的能力可被用来攻击其他 站点,而能够访问强大能力也会使站点成为 不良行为者更有吸引力的目标。为了缓解这些风险, 任何通过本规范中描述的机制被授予能力访问权的内容, 都必须与用户的正常浏览会话隔离。
本规范定义了隔离上下文,它们是满足 完整性和隔离性的最低标准的环境,并提供一种 为了可信度证明而审计 Web 内容的手段,并且 将这些内容与用户其余浏览数据隔离开来。
虽然本规范侧重于用户代理提供的能力,但隔离 上下文可能对任何其威胁模型不被 Web 安全模型 满足的网页功能都有益。例如,某些端到端加密 聊天应用的威胁模型包含服务器被攻破,而 当今 Web 并不能防范这种情况。隔离上下文启用的 可审计性和证明可允许这些应用确信其正在运行的 代码的完整性和来源。
2. 隔离上下文
隔离上下文 通过对现有规范的一系列 § 3 猴子补丁来定义。
完整性通过严格的 [CSP] 与完整性验证 算法的组合来验证,前者确保 不能加载跨源可执行内容,后者是一种用于验证页面内 加载内容的抽象机制。本规范不强制规定具体的验证方法, 只定义如何使用某种方法来确定一个环境是否为 隔离上下文。
2.1. 哪些 API 应要求隔离上下文?
越少越好。任何只能暴露给隔离上下文的 API, 很可能至少违反了 Web 的一项设计 原则,最常见的是访问一个网页应当是安全的。 在要求使用某个 API 之前必须处于隔离上下文中时, 请考虑以下问题:
-
新的 Web 平台 API 是否是解决该 API 试图解决的问题的 唯一方式?Web 扩展和原生应用有其适用位置。
-
如果某项能力无法清晰地传达给用户,是否有另一种 对用户而言更易理解的方式来解决该问题,并 允许他们就哪些内容可以访问它作出知情决定?
-
是否可以缩小该 API 的范围,使其在暴露给普通网页时 不再造成不可接受的风险?
如果找不到替代方案,可以将要求 API 在隔离 上下文中运行作为最后手段来考虑。
Web 之所以成为如此独特且成功的平台,部分原因在于 它没有把关者。任何人都可以购买域名并托管其内容, 无需任何其他人的批准,并且可以完全访问 Web 平台的 API 表面;每个人都有同等立足点。隔离 上下文提供的安全保证启用可审计性,进而启用证明。 由浏览器供应商或第三方提供的证明所带来的安全性, 是 API 会被限制到隔离上下文的主要原因。提供证明服务的 各方有可能成为 Web 平台的把关者,这不是平台 理想的发展方向。浏览器供应商必须极其谨慎地选择 允许哪些 API 进入隔离上下文;只要可能,就应强烈 优先考虑修改 API,使其能够在安全上下文中使用。
2.2. UI 处理方式
本规范侧重于实现完整性和隔离性所需的技术要求, 但如果隔离上下文被用于启用 强大能力,则不违反用户预期也至关重要。
用户信任 Web,是因为他们被教导网页是安全的、 对其设备的访问受限,并且他们可以控制这种访问。Web 平台上的所有 API 都是朝着这一目标精心设计的,目标是确保 访问一个网页应当是 安全的。
浏览器供应商应考虑限制到隔离 上下文的能力是否会违反用户对网页能够做什么的预期。 违反这些预期不仅会损害对该站点的信任, 还可能损害用户对整个 Web 平台的信任。
为了缓解这一点,用户代理应采取步骤向用户传达: 在隔离上下文中运行的内容不是典型的 Web 内容。这 可以涉及安装流程,或 Web App UI 处理方式。
3. 猴子补丁
本规范对现有规范作出以下猴子补丁:
-
对 [CSP] 的补丁将定义某个策略所需的特征, 这些特征足够稳健, 能够有意义地防御攻击,并强制不能加载跨源 内容。它建立在我们从 [strict-csp] 和 [securer-contexts] 等探索中学到的东西之上,推动开发者采用 已充分理解且有价值的防御。
-
对 [HTML] 的补丁将 定义在给定上下文内评估这些 CSP 特征以及其他安全要求的方式, 其概念上类似于安全上下文和跨源隔离 能力。它还将 定义验证某个用户代理资源的完整性所需的源属性。
-
对 [WEBIDL] 的补丁将定义
[IsolatedContext]属性,以及 它如何依赖上述变更来控制给定 WebIDL 构造的暴露方式。
3.1. 内容安全策略
在 [CSP] 中,我们将 定义一个算法,用于评估包含在 CSP 列表中的 策略合并体的强度。我们还将定义一些 支持算法,但 § 3.1.1 策略是否能有意义地缓解注入攻击? 是 CSP 将暴露给 HTML 的核心入口点。
3.1.1. 策略是否能有意义地缓解注入攻击?
Meaningful”,则称一个 CSP
列表 policies 有意义地
缓解注入攻击。可能的返回值为“Meaningful”和
“Not meaningful enough”。
-
令 meets object requirements、meets base requirements、meets script requirements、meets style requirements、meets subresource requirements 和 meets trusted type requirements 为值为
false的布尔值。 -
对 policies 中的每个 policy 执行:
-
如果 policy 充分缓解 插件,则将 meets object requirements 设为
true。 -
如果 policy 充分 缓解相对 URL 操纵,则将 meets base requirements 设为
true。 -
如果 policy 充分缓解 脚本执行,则将 meets script requirements 设为
true。 -
如果 policy 充分缓解 样式求值,则将 meets style requirements 设为
true。 -
如果 policy 充分阻止 不安全子资源,则将 meets subresource requirements 设为
true。 -
如果 policy 充分缓解 DOM 接收器,则将 meets trusted type requirements 设为
true。
-
如果 meets object requirements、meets base requirements、meets script requirements、meets style requirements、meets subresource requirements 和 meets trusted type requirements 均为
true,则返回“Meaningful”。 -
返回“
Not meaningful enough”。
3.1.2. 获取某类型的有效指令
3.1.3. 策略是否充分缓解插件?
3.1.4. 策略是否充分缓解相对 URL 操纵?
3.1.5. 策略是否充分缓解脚本执行?
Sufficient”,则一个策略
policy 充分缓解脚本执行。
可能的返回值为“Sufficient”和“Not sufficient”。
-
给定“
script-src”,从 policy 获取 active directive。 -
如果以下各项均为真,则返回“
Sufficient”:-
active directive 不是 null
-
active directive 中的所有源表达式 都是与字符串 “
'none'”、“'self'”或 “'wasm-unsafe-eval'”进行 ASCII 大小写不敏感匹配的结果。
-
-
返回“
Not sufficient”。
3.1.6. 策略是否充分缓解样式求值?
Sufficient”,则一个策略
policy 充分缓解样式求值。
可能的返回值为“Sufficient”和“Not sufficient”。
-
对 policy 的指令集中的每个 directive 执行:
-
给定“
style-src”,从 policy 获取 active directive。 -
如果以下各项均为真,则返回“
Sufficient”:-
directive 的名称为“
style-src”。 -
active directive 中的所有源表达式都是与 字符串 “
'none'”、“'self'”或 “'unsafe-inline'”进行 ASCII 大小写不敏感匹配的结果。
-
-
-
返回“
Not sufficient”。
3.1.7. 策略是否充分阻止不安全子资源?
3.1.8. 策略是否充分缓解 DOM 接收器?
Sufficient”,则一个策略
policy 充分缓解 DOM 接收器。
可能的返回值为“Sufficient”和“Not sufficient”。
-
对 policy 的指令集中的每个 directive 执行:
-
如果以下各项均为真,则返回“
Sufficient”:-
directive 的名称为 “
require-trusted-types-for”。 [TRUSTED-TYPES] -
directive 的值 包含[0] 一个与 字符串“
'script'”进行 ASCII 大小写不敏感匹配的结果。
-
-
-
返回“
Not sufficient”。
3.1.9. 示例
以下 CSP 有意义地缓解注入 攻击:
base-uri 'none'; default-src 'self'; object-src 'none'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src 'self' https: blob: data:; connect-src 'self' https: blob: data:; img-src 'self' https: blob: data:; media-src 'self' https: blob: data:; font-src 'self' blob: data:; require-trusted-types-for 'script';
3.1.10. 策略是否能有意义地缓解 UI 伪装攻击?
Meaningful”,则称一个 CSP
列表 policies 有意义地
缓解 UI 伪装攻击 [UISECURITY]。
可能的返回值为“Meaningful”和“Not meaningful enough”。
3.2. HTML
在 HTML 中,我们将定义一些用于资源完整性验证的属性, 以及一些与 § 3.1 内容安全 策略中定义的算法结合使用的算法,以定义环境设置对象的特征。在确定给定 IDL 构造是否暴露在 关联的全局对象上时,这些特征将由 [WEBIDL] 检查。
3.2.1. 完整性
完整性 验证算法是一个由实现定义的算法,它接受一个请求和一个响应,并 返回一个布尔值。
注:典型的完整性 验证算法可能验证 响应体是否哈希为预期值,或它是否源自已知的 资源包。
用户 代理持有一个源完整性验证映射, 它是一个从元组源到完整性 验证算法的映射。
注:用户代理如何填充源完整性验证映射, 不在本规范范围内;本规范关注建立完整性和隔离性所需的 属性。Isolated Web Apps 提供了一种可能的实现,其方式是将此映射基于已安装的 Isolated Web Apps 集合。
3.2.2. 环境设置对象属性
注:由于 CSP 列表中有意义的注入和 UI 伪装 缓解的定义仅依赖于通过标头交付的策略, 因此这些属性在环境的生命周期内不会变化。
true,则一个环境设置对象 environment 是一个
隔离上下文:
-
如果 environment 没有有意义地 缓解注入攻击,则返回
false。 -
如果 environment 没有缓解 UI 伪装攻击,则返回
false。 -
令 origin 为 environment 的源。
-
返回
true。
3.3. Fetch
在 Fetch 中,我们将使用 完整性验证算法(定义于 § 3.2.1 完整性)来验证响应是否具有预期内容。
3.3.1. 验证响应的完整性
not applicable”、“invalid”或“valid”。
- 令 client 为 request 的客户端。
- 如果 client 为
null,则返回“not applicable”。 - 令 origin 为 request 的源。
- 如果用户代理的源
完整性验证映射[origin]
不存在,则返回“
not applicable”。 - 令 integrity verification algorithm 为用户代理的源完整性验证 映射[origin]。
- 如果 response 的主体为
null,则返回“invalid”。 - 如果给定 request 和
response 执行 integrity verification algorithm 的结果为
false,则返回“invalid”。 - 返回“
valid”。
3.3.2. 对“Main Fetch”算法的补丁
main fetch 算法扩展如下:- 令 request 为 fetchParams 的请求。
- 令 response 为
null。 -
如果 request 的完整性元数据不是空字符串,
则:
- ...
-
如果给定
request 和 response 执行验证响应的完整性的结果为
“
invalid”,则给定 fetchParams 和一个网络错误运行 fetch response handover。 - 否则,给定 fetchParams 和 response 运行 fetch response handover。
注:理想情况下,我们会将完整性验证 与 [SRI] 的完整性元数据及其支持算法集成。 这将需要对 [SRI] 规范处理完整性元数据字符串的方式进行 非平凡的重构,这在未来可能值得推进。
3.4. WebIDL
在 WebIDL 中,我们将定义 [IsolatedContext] 属性,并将其连接到
上述 HTML 中创建的钩子:
3.4.1. [IsolatedContext]
如果 [IsolatedContext]
扩展属性出现在接口、部分接口、接口混入、
部分接口混入、回调接口、命名空间、部分命名空间、接口
成员、接口混入成员或命名空间
成员上,
则表示该构造仅在
隔离上下文中暴露。
[IsolatedContext]
扩展属性不得用于
任何其他构造。
[IsolatedContext]
扩展属性必须不接受
参数。
如果 [IsolatedContext]
出现在一个重载操作上,
则它必须出现在所有重载上。
[IsolatedContext]
扩展属性不得在以下多于一项上指定:
注:这是因为,当包含定义也已用
[IsolatedContext]
扩展属性标注时,在成员上添加 [IsolatedContext]
扩展属性,不会进一步限制该
成员的暴露。
没有 [IsolatedContext]
扩展属性的接口,不得继承自另一个
指定了 [IsolatedContext]
的接口。
3.4.2. 对“exposed”算法的补丁
WebIDL 的exposed算法调整如下,在类似处理
[CrossOriginIsolated]
之后添加一个步骤(下方步骤 4)。
- 如果 construct 的暴露
集不是
*,并且 realm.[[GlobalObject]] 没有实现一个位于 construct 的暴露集中的接口,则返回 false。 - 如果 realm 的设置对象不是安全上下文,并且 construct 在 [
SecureContext] 上有条件地暴露,则 返回 false。 - 如果 realm 的设置对象的跨源隔离
能力为 false,
并且 construct 在 [
CrossOriginIsolated] 上有条件地暴露, 则返回 false。 -
如果 realm 的设置对象不是隔离
上下文,
并且 construct 在 [
IsolatedContext] 上有条件地暴露, 则返回false。 - 返回 true。
3.5. 存储
为非存储 目的获取存储键算法被扩展为: 要求对属于某个环境的所有存储进行双重键控, 该环境具有一个被用户 代理已知为拥有完整性验证算法的 顶级源。
注:这本质上是 客户端存储分区的一个最小指定版本。当 该机制被完整指定并合并 到必要的规范中时,这些变更将取代本节, 并且本节可以移除。