这是官方安全公告的交叉发布版本。官方公告中也包含我们 PGP 密钥签名的版本。
Rust 安全响应工作组接到通知,标准库函数 std::fs::remove_dir_all
存在一个竞态条件漏洞,可导致符号链接跟踪 (CWE-363)。攻击者可以利用此安全问题欺骗特权程序删除攻击者原本无法访问或删除的文件和目录。
此问题已被分配 CVE-2022-21658。
概述
假设攻击者获得了系统的非特权访问权限,并且需要删除一个名为 sensitive/
的系统目录,但他们没有权限执行此操作。如果 std::fs::remove_dir_all
遵循符号链接,攻击者可以找到一个有特权、会删除他们有权访问的目录(称为 temp/
)的程序,然后从 temp/foo
创建一个指向 sensitive/
的符号链接,并等待特权程序删除 foo/
。特权程序在递归删除时将遵循从 temp/foo
到 sensitive/
的符号链接,导致 sensitive/
被删除。
为了防止此类攻击,std::fs::remove_dir_all
已经包含保护措施,避免递归删除符号链接,如其文档中所述:
此函数**不**遵循符号链接,它只会删除符号链接本身。
不幸的是,该检查在标准库中的实现不正确,导致了 TOCTOU(Time-of-check Time-of-use,检查时间与使用时间之间)竞态条件。标准库没有指示系统不遵循符号链接,而是首先检查要删除的对象是否是符号链接,如果不是,则继续递归删除目录。
这暴露了一个竞态条件:攻击者可以在检查和实际删除之间创建一个目录并将其替换为符号链接。虽然这种攻击首次尝试时可能不会成功,但在我们的实验中,我们能够在几秒钟内可靠地执行此操作。
受影响版本
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 审查了补丁。