标准库安全公告 (CVE-2024-24576)

2024 年 4 月 9 日 · Rust 安全响应工作组

Rust 安全响应工作组收到通知,Rust 标准库在使用 Command API 在 Windows 上调用批处理文件(扩展名为 batcmd)时,没有正确地转义参数。攻击者能够控制传递给已生成进程的参数,可以通过绕过转义来执行任意 shell 命令。

如果您在 Windows 上使用不可信参数调用批处理文件,此漏洞的严重程度为 **严重**。其他平台或使用不受影响。

此漏洞的标识符为 CVE-2024-24576。

概述

Command::argCommand::args API 在其文档中说明,无论参数的内容如何,参数都将按原样传递给已生成的进程,并且不会由 shell 评估。这意味着将不可信输入作为参数传递应该是安全的。

在 Windows 上,此实现比其他平台更复杂,因为 Windows API 仅提供一个包含所有传递给已生成进程的参数的字符串,并且由已生成进程来拆分它们。大多数程序使用标准 C 运行时 argv,这在实践中导致参数拆分的方式基本一致。

不过,一个例外是 cmd.exe(用于执行批处理文件等),它有自己的参数拆分逻辑。这迫使标准库为传递给批处理文件的参数实现自定义转义。不幸的是,据报道我们的转义逻辑不够彻底,并且有可能传递恶意参数,从而导致任意 shell 执行。

缓解措施

由于 cmd.exe 的复杂性,我们没有找到在所有情况下都能正确转义参数的解决方案。为了维护我们的 API 保证,我们改进了转义代码的健壮性,并将 Command API 更改为在无法安全转义参数时返回 InvalidInput 错误。此错误将在生成进程时发出。

此修复程序将包含在 Rust 1.77.2 中,该版本将于今天晚些时候发布。

如果您自己实现转义或仅处理可信输入,在 Windows 上,您还可以使用 CommandExt::raw_arg 方法绕过标准库的转义逻辑。

受影响的版本

如果您的代码或您的依赖项之一使用不可信参数执行批处理文件,则 Windows 上所有早于 1.77.2 的 Rust 版本都会受到影响。Windows 上的其他平台或其他用途不受影响。

致谢

我们要感谢 RyotaK 按照 Rust 安全策略 向我们负责任地披露了此问题,还要感谢 Simon Sawicki (Grub4K) 识别出我们在修复中采用的某些转义规则。

我们还要感谢帮助我们披露此漏洞的 Rust 项目成员:Chris Denton 开发了修复程序;Mara Bos 审查了修复程序;Pietro Albini 撰写了此公告;Pietro Albini、Manish Goregaokar 和 Josh Stone 协调了此披露;Amanieu d'Antras 在披露期间提供了建议。