Vercel公布百万美元沙箱安全挑战结果,未收到访问客户数据的报告。最严重发现涉及Linux网络栈:研究者从普通微虚拟机内发送特制数据包,演示了宿主机内存泄露、崩溃等攻击。
今年 8 月,我们发起了 Vercel Sandbox 百万美元黑客挑战赛,邀请安全研究人员尝试逃逸 Vercel Sandbox。我们还与网络安全专家 Trail of Bits 合作,审查了源代码和安全架构。
以下是本次挑战赛的概况:
两周内收到 1,285 份报告
两周内收到 1,285 份报告
发放 242,000 美元漏洞赏金
发放 242,000 美元漏洞赏金
发现一个 Linux 内核零日漏洞
发现一个 Linux 内核零日漏洞
没有任何报告表明有人访问了 Vercel Sandbox 中的客户数据。最严重的发现是上游 Linux 内核中的缺陷。
本次活动最重要的报告出现在第三天。
HackerOne 研究人员 Paulos Yibelo(pwn.ai)在一个没有任何特殊访问权限的标准 sandbox 中,发现了 Linux 内核网络栈的一个缺陷。Paulos 发现,从 microVM 内部发送特制数据包,可以发起三种不同的攻击:
通过网络泄露宿主机内存
通过网络泄露宿主机内存
使宿主机崩溃
使宿主机崩溃
在宿主机上执行代码
在宿主机上执行代码
在第一种攻击中,宿主机的内存会出现在客户机发往互联网的数据包里。宿主机就是你的 sandbox 与其他租户共用的那台机器。只要客户机持续发送数据包,这种泄露就可以持续发生。
这项攻击已在 Vercel 生产环境的 sandbox 上得到验证。
研究人员还发现,通过发送特定数据包,可以攻陷宿主机。
首先,研究人员只发送了两个数据包,就让宿主机崩溃,导致其上运行的所有 sandbox 全部关闭。其次,利用同一个缺陷,他们能够以完整的管理员权限在宿主机上运行命令,突破 sandbox 的隔离边界。
与数据包相关的崩溃和代码执行攻击,是在研究人员自己的 KVM 和 Firecracker 机器上验证的,这些机器采用了与 Vercel Sandbox 一致的配置。
几乎所有主要云服务商都在 Linux 内核的同一层隔离客户工作负载,因此,这一层的任何缺陷都会给共享基础设施带来风险。
收到通知后,我们立即与研究人员合作,了解并缓解这个漏洞,同时与 AWS 及其他行业合作伙伴协作,优先推进修复,确保 Vercel 客户以及其他使用该内核的开发者的安全。
研究人员也联系了内核维护者,并与他们一起编写候选补丁。修复方案仍在非公开审查中,CVE 编号也尚待分配,因此,在补丁公开之前,我们不会发布更多细节。我们之所以披露这个漏洞的存在,是因为它已经由其他渠道公开披露。
HackerOne 挑战赛面向所有研究人员提供漏洞赏金,但我们的计划还包括内部评估和独立调查。
在公开漏洞赏金活动启动之前,我们就开展了内部实测安全评估,评估人员可以完整访问源代码,并得到 Vercel Sandbox 开发和维护工程师的支持。我们还聘请了 Trail of Bits,由他们派出两名工程师评估我们的安全架构。
并非所有问题都来自外部。Vercel 实习生 Marcos Hernanz 在 Linux 的 device-mapper 存储层中发现了一个跨租户数据泄露漏洞。这个漏洞让任意 sandbox 都能读取此前已删除 sandbox 所使用、随后被回收的磁盘块。
Trail of Bits 在我们的源代码上投入了四个工程师周的审查工作,可以完整访问代码仓库和两个企业测试团队。他们提交了 20 项发现,每一项都经过测试和确认,并明确对应到具体代码。
他们还开展了架构审查,认定我们的虚拟化边界设计可靠。每个 sandbox 都运行在独立的 Firecracker microVM 上,拥有专用的客户机内核,设备模型也被刻意精简。客户机不会与宿主机或其他租户共享运行中的内核。
在这个基础上,他们提出了三项结构性建议,我们均已落实:
找出并消除对客户机的一切信任。我们的控制平面曾接受 microVM 内运行的软件返回的值,而这些值无一例外都属于租户输入。任何跨越边界的数据,都应该在服务端推导生成,或使用客户机无法访问的密钥进行签名。
找出并消除对客户机的一切信任。我们的控制平面曾接受 microVM 内运行的软件返回的值,而这些值无一例外都属于租户输入。任何跨越边界的数据,都应该在服务端推导生成,或使用客户机无法访问的密钥进行签名。
一套策略,一个决策方。出站流量管控曾分散在多个子系统中,各个子系统独立解析同一套网络策略,结果却不总是一致。现在,我们为每种数据类型统一使用一套规范化处理流程,每项决策由一个组件负责,并在策略发生变化时重新验证连接。
一套策略,一个决策方。出站流量管控曾分散在多个子系统中,各个子系统独立解析同一套网络策略,结果却不总是一致。现在,我们为每种数据类型统一使用一套规范化处理流程,每项决策由一个组件负责,并在策略发生变化时重新验证连接。
假定下一个零日漏洞一定会出现。我们强化了每个 sandbox 周围的防护,以便在攻击者利用虚拟化软件漏洞时限制损害。我们持续更新宿主机内核,禁用了嵌套虚拟化,并使用 Firecracker 的 jailer,以受限权限运行每个 microVM 进程,将其与宿主机的其他部分隔离。
假定下一个零日漏洞一定会出现。我们强化了每个 sandbox 周围的防护,以便在攻击者利用虚拟化软件漏洞时限制损害。我们持续更新宿主机内核,禁用了嵌套虚拟化,并使用 Firecracker 的 jailer,以受限权限运行每个 microVM 进程,将其与宿主机的其他部分隔离。
我们在两周内收到了 1,285 份报告。能达到这样的数量,是因为研究人员如今已经在以 AI 的速度寻找漏洞。
以下是报告的分类情况:
在报告分诊过程中,我们已验证:
32 项 Informative 级别发现
32 项 Informative 级别发现
我们已发放 242,000 美元漏洞赏金。
Medium、Low 和 Informative 级别的发现,都是策略边界上的小缺口,例如某条防火墙规则的实际行为与文档描述不同,或某个字段对客户机给予了过多信任。
最严重的发现是 Linux 内核零日漏洞,没有任何报告表明有人读取了客户的文件、密钥或应用数据。
最让我们印象深刻的是报告的多样性。可以明显看出,研究人员使用了不同的环境,也各有钻研的方向。有些人显然非常熟悉 Linux namespaces,直接引导自己的 Agent 攻向内核边界。另一些人盯上了网络策略,还有很多人研究的是我们根本没想到要列入测试范围的领域。
公开挑战赛所投入的资金,换来的正是这种多样性。下面是其中一个比较有意思的发现。
这份报告在挑战赛第一天提交,是我们最喜欢的例子:即使已经做过内部评估和白盒审查,我们依然有必要开展公开漏洞赏金活动。
为 sandbox 创建快照时,控制平面需要记录快照数据存放的位置:{storage_url, size, checksum}。研究人员发现的缺陷很隐蔽:这份结果来自客户机内部运行的软件,而宿主机上的服务却信任了它。这违反了信任边界。客户机是客户(以及黑客)运行不可信代码的地方,因此宿主机绝不能把客户机的说法当作权威依据。
研究人员将一个已知且有文档记录的容器逃逸原语,与这个信任缺陷结合起来。他们在自己的 sandbox 内拦截并改写快照响应,将自己持有的两个不同账号下的两个快照的存储对象互换。这样一来,恢复“你的”快照时,实际还原出来的却是另一个账号的完整文件系统。
研究人员证明,两个账号都可以读取和修改对方的文件,并通过哈希值验证结果,还保留了测试资源,方便我们独立复现这些发现。
这项攻击的限制非常关键。要把互换目标指向某个特定受害者,就必须知道该受害者的内部快照存储键。这是平台为每个快照生成的随机 96 位标识符,从不通过 API 暴露。这个键只会出现在受害者自己的 sandbox 内。研究人员持有两个账号,才得以完成验证;他们没有证明陌生人能够通过某条路径,将其他租户作为攻击目标。即便如此,我们仍将其列为优先修复事项,因为如果一道边界的成立依赖于秘密始终不泄露,那它就算不上一道边界。
Trail of Bits 在评估中也独立指出了同一个根因,这说明该问题确实存在、影响重大,而且可以从两个完全不同的角度被发现。
修复在一周内上线。现在,控制平面会将每个快照对象绑定到创建它的项目,并拒绝任何不匹配的对象。快照创建操作已从客户机可触及的环境迁移到宿主机侧服务,存储路径按项目划分作用域,并对 URL 进行严格验证。
我们感谢每一位提交报告的研究人员,无论他们发现的是零日漏洞,还是重复问题。挑战赛中发现的每一种技术,都为我们保护 Vercel Sandbox 上运行的工作负载提供了参考。
也感谢 Trail of Bits 全面的内部调查和指导。
欢迎阅读最初的挑战赛公告,并通过文档进一步了解 Vercel Sandbox。