标准库安全公告 (CVE-2022-21658)

2022年1月20日 · Rust 安全响应工作组

这是官方安全公告的交叉发布。官方公告还包含使用我们的 PGP 密钥签名的版本。

Rust 安全响应工作组收到通知,std::fs::remove_dir_all 标准库函数存在竞争条件漏洞,允许符号链接跟踪 (CWE-363)。攻击者可以利用此安全问题,欺骗特权程序删除攻击者原本无法访问或删除的文件和目录。

此问题已被分配为 CVE-2022-21658

概述

假设攻击者获得了对系统的非特权访问,需要删除名为 sensitive/ 的系统目录,但他们没有权限这样做。如果 std::fs::remove_dir_all 跟踪符号链接,他们可以找到一个有权删除他们有权访问的目录(名为 temp/)的特权程序,创建一个从 temp/foosensitive/ 的符号链接,并等待特权程序删除 foo/。特权程序将在递归删除时跟踪从 temp/foosensitive/ 的符号链接,导致 sensitive/ 被删除。

为了防止此类攻击,std::fs::remove_dir_all 已经包含了防止递归删除符号链接的保护机制,如其文档中所述。

此函数跟踪符号链接,它只会删除符号链接本身。

不幸的是,该检查在标准库中实现不正确,导致了 TOCTOU(检查时间-使用时间)竞争条件。标准库没有告诉系统不要跟踪符号链接,而是首先检查它即将删除的东西是否为符号链接,否则它将继续递归删除目录。

这暴露了一个竞争条件:攻击者可以创建一个目录,并在检查和实际删除之间将其替换为符号链接。虽然这种攻击可能不会第一次尝试就成功,但在我们的实验中,我们能够在几秒钟内可靠地执行它。

受影响的版本

Rust 1.0.0 到 Rust 1.58.0 受此漏洞影响。我们将在今天晚些时候发布 Rust 1.58.1,其中将包含针对此漏洞的缓解措施。Rust 标准库的补丁也适用于自定义构建的 Rust 工具链,请点击此处查看。

请注意,以下目标没有可用的 API 来正确缓解此攻击,因此即使使用已打补丁的工具链仍然容易受到攻击

  • macOS 10.10 (Yosemite) 之前的版本
  • REDOX

缓解措施

我们建议每个人尽快更新到 Rust 1.58.1,特别是那些开发预计在特权上下文中运行的程序(包括系统守护程序和 setuid 二进制文件)的人员,因为他们受此影响的风险最高。

请注意,在调用 remove_dir_all 之前在代码库中添加检查不会缓解此漏洞,因为它们也容易受到像 remove_dir_all 本身那样的竞争条件的影响。现有的缓解措施在竞争条件之外按预期工作。

致谢

我们要感谢 Hans Kratz 根据 Rust 安全策略独立发现并向我们披露此问题,为类 UNIX 目标开发修复程序,并审查其他平台的修复程序。

我们还要感谢 Florian Weimer 审查了类 UNIX 的修复程序,并在 2018 年报告了相同的问题,尽管当时安全响应工作组没有意识到该问题的严重性。

最后,我们要感谢 Pietro Albini 协调安全响应并撰写此公告,Chris Denton 编写 Windows 修复程序,Alex Crichton 编写 WASI 修复程序,以及 Mara Bos 审查补丁。