标准库安全通报 (CVE-2024-24576)

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

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

如果您在 Windows 上使用不受信任的参数调用批处理文件,此漏洞的严重性为关键(critical)。其他平台或用途不受影响。

此漏洞的标识符为 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 在披露期间提供了建议。