标准库的安全公告 (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/foo 创建一个指向 sensitive/ 的符号链接,并等待特权程序删除 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 审查补丁。