理解 Chromium 中的 Rule-Of-2
2025-03-19
性能、可靠、安全,是现代软件开发的理想目标。
尽管通常不可兼得。
就像 CAP 理论描述的那样,理想丰满,现实骨感。
这三者中,安全往往是最容易被忽略的。
我想原因大概有两个。
一是安全事件发生频率低,很少引起重视。
另外,完备的基础设施,例如 HTTPS,现代浏览器,屏蔽了大部分风险,导致很多人误以为网络世界很安全。
其实无论何时,在开发中,防御(Defensive)的意识都要有。
在微软内部,安全的课程每年都会更新,而且反复强调。
毫无疑问,网络世界很复杂,隐藏在暗中的攻击者,去中心化的匿名组织,数以百亿的用户访问,如何保证普通用户和服务的安全?
Chromium 提出了一套简单且通用的 Rule Of 2 准则。
1. 概念
The Rule Of 2 的概念非常简单,就是:
- 不可信输入(Untrusted Inputs)
- 不安全编程语言(Unsafe implementation language)
- 高特权(High Privilege)
如果实现中同时包含三者,将会非常危险!
因此建议,最多包含其中两者。

不可信输入有两种:不可信输入内容,以及不可信输入源。
浏览器每天需要访问形形色色的网站,加载第三方脚本,没有办法假设它们都是安全的。
可信的输入源,通常被认为是安全的。不过按照 Zero Trust 的思路,仍然需要验证。
不安全编程语言指的就是内存不安全,例如 C/C++、汇编语言等。内存安全语言,有 Go、Rust、Python 和 Java 等。
根据微软 2019 年的 报告🔗,
每年通过安全更新解决的漏洞中,约 70% 仍然是内存安全问题。
这与 Chromium 的 bug tracker 结果基本一致(截止 2019 年 3 月,130 个公开的严重漏洞中,只有 5 个明确与内存安全无关)。
高特权,意味着拥有自由访问底层资源的能力,例如网络、文件系统、摄像头等。
一方面,权限越高,可做的事情越多,反过来,一旦出错,危害也更大。
2. 实践
Chromium 在 2023 年 8 月 宣布🔗,将默认采用 HTTPS。
从源头屏蔽掉不可信输入源。
归一化(Normalization)可以解决不可信输入内容的问题。
通俗地讲,就是将恶意输入转换为一套固定形式,从无限空间映射到有限空间。例如将 URL 转换为 GURL
,一种通用的 URL 表达方式。
Chromium 的大部分代码都是用 C++ 写的,不过有很多内存安全语言已经被允许使用:
QR 码生成器🔗 QR 码生成器 Chromium 中使用跨平台内存安全 Rust 库的一个示例。
Chromium 本身是 多进程架构🔗,这种多进程可分为纵向和横向两部分。
纵向的,JavaScript 等外部脚本在 Render 进程执行,而 Render 进程是一个 沙盒进程🔗,如访问文件、网络请求等,需委托拥有更高权限的进程。
横向的,Chromium 有站点隔离策略(Site Isolation),不同站点分属不同的 Render 进程,资源不共享,其中一个进程 Crash,也不会影响其他站点的正常访问。
3. 借鉴
起初我在思考这个问题的时候,毫无头绪,认为网络上各种 case 都有可能发生,几乎不可能保证不出问题。
The Rule Of 2 很好地诠释了什么是化繁为简。
用简单的原则,对冲复杂的问题,找到第一性原理。这是给我的第一点启发。
与计算机一样,浏览器就做了三件事:
- 输入(Input)
- 执行(Execute)
- 输出(Output)
在我看来,这里就对应了 Rule Of 2 里的三点。
- 输入不可靠
- 执行可能出问题
- 输出会带来危险
只要打破其中一个,风险链条就断了。
代码中的 bug 不可避免。头疼医头,脚疼医脚,疲于奔命,不解决本质问题。要正本清源,在设计阶段就体现安全意图。
这是我的第二点思考。
4. 总结
Rule Of 2 看似简单,实则背后有着对安全问题的本质思考。
抽象能力,是高级程序员,与普通程序员的最大区别。
(完)
参考
- 本文作者:Plantree
- 本文链接:https://plantree.me/blog/2025/rule-of-2-chromium/
- 版权声明:所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
最后更新于: 2025-04-08T01:48:11+08:00