内容提要
处理不可信输入时需遵循规则:1. 复杂语法且来源不可信的输入视为不可信,除非可证明其可信性。2. C、C++和汇编语言不安全,Go、Rust、Python、Java、JavaScript、Kotlin和Swift更安全。3. 高权限包括固件、内核、管理程序,低权限包括沙箱实用程序和隔离渲染器进程。
延伸解读
规则的核心逻辑:三者不可兼得
文章提出的“2规则”指出,在处理不可信输入时,不可信输入、不安全语言和高权限三者中最多只能同时存在两个。如果三者同时出现,就构成安全漏洞。这一规则帮助开发者在设计系统时快速识别风险组合,例如使用C++处理网络数据且运行在高权限下,就违反了规则。
如何界定不可信输入
不可信输入需满足两个条件之一:语法复杂,或来源不可信。如果语法足够简单,可以编写内存安全的处理程序,则来源风险降低;但解析后仍需视为不可信。对于来源,除非能证明其可信性(如身份强断言和HTTPS完整性保护),否则任何互联网对等点都不可信。即使可信,也建议在沙箱中解析以降低信任。
语言选择与权限层级
C、C++和汇编语言缺乏内存安全,属于不安全语言;Go、Rust、Python、Java、JavaScript、Kotlin和Swift则被视为内存安全语言。高权限包括固件、引导加载程序、内核、管理程序等;低权限包括沙箱实用程序和隔离渲染器进程。在高权限环境中,应优先使用内存安全语言,且所有代码(包括不安全代码)都必须满足规则2。
Q&A
谷歌安全2规则具体指哪三个选择?
三个选择是:不可信的输入、不安全的实现语言、高权限。规则要求在这三个中选择不超过两个,如果三个同时出现,就会导致安全漏洞。
什么样的输入会被视为不可信?
具有复杂语法且来源不可信的输入被视为不可信。如果输入语法足够简单,可以直接编写内存安全的处理程序,则不需要担心其来源;否则,来自互联网任意对等点的输入都不可信,除非能证明其可信性(如来源身份有力断言和完整性保护传输)。
哪些编程语言被认为是不安全的?哪些是安全的?
不安全的实现语言包括C、C++和汇编语言,因为它们缺乏内存安全性。内存安全语言包括Go、Rust、Python、Java、JavaScript、Kotlin和Swift。
高权限具体包括哪些组件?
高权限包括计算机固件、引导加载程序、内核、管理程序或虚拟机监控程序,以及以操作系统级账户代表个人运行的进程(如Chrome浏览器进程和Gpu进程)。权限略微降低的进程包括网络进程,低权限进程包括沙箱实用程序和具有站点隔离或起源隔离功能的渲染器进程。
如何安全地处理来自可信来源的复杂输入?
如果输入来自与应用程序本身相同的来源(例如Chrome浏览器的来源是Google,火狐浏览器的来源是Mozilla),并且传输是受完整性保护的(例如HTTPS),那么即使是复杂输入也可以接受解析。但理想情况下,仍应降低对来源的信任度,例如在沙箱中解析输入。
为什么内存安全语言在高权限环境中更安全?
内存安全语言(如Go、Rust等)缺乏内存安全问题,因此在高权限环境中使用这些语言的代码应该是安全的。而不安全语言(如C、C++)需要遵循严格规则以避免未定义行为,且需要专家审查。内存安全语言中的所有代码(包括不安全代码)必须能在高权限上下文中满足第2条规则,才能被允许使用。