SafeDep 表示,受污染的 arrayref 发布版在 Rust 构建期间运行了恶意软件
SafeDep 记录了 8 月 20 日的一起妥协事件:arrayref 0.3.10 拉取了一个错拼依赖,该依赖在编译期间运行了一个远程二进制文件;crates.io 随后才删除这些恶意包。
By RuntimeWire Staff · Published
Primary source: SafeDep
Why it matters
The attack abused Cargo's normal build process, showing why dependency security is moving from advisory feeds to controls that block packages before their scripts execute.

SafeDep,由 Abhisek Datta (@abh1sek) 联合创立的供应链安全初创公司,于 2026 年 8 月 20 日 报告,称一个被入侵的广泛使用的 Rust 包 arrayref 的发布版在编译期间下载并执行了恶意软件。根据 SafeDep 的说法,crates.io 团队随后删除了这些恶意包。 (safedep.io)
该攻击将一次普通的 Cargo 构建变成了投递机制。arrayref 版本 0.3.10 添加了对 proc-macro1 的依赖 —— 一个冒充合法包 proc-macro2 的包。Cargo 自动编译了该依赖,从而导致其 build.rs 脚本从远程服务器获取并启动了一个二进制文件。开发者只需编译一个在依赖解析时选中被污染发布版的项目即可触发。
对 Datta 来说,这个案例正好落在他职业生涯一直在研究的问题范围内。他的 公开简介 描述了早期从事漏洞研究、逆向工程和恶意软件分析的工作,随后创办了安全咨询公司 3S Labs 并在 Appsecco 担任技术负责人。SafeDep 现在将这些经验打包成产品,旨在在依赖到达笔记本、仓库、编码代理或 CI 系统之前进行检查,包括 SafeDep 的开源 package monitor。 (abhisek.github.io)
同日包链
SafeDep 表示,2026 年 8 月 20 日,恶意的 proc-macro1 1.0.107 以及显然被入侵的 droundy 账号的 arrayref 0.3.10 出现在 crates.io。 RustSec 报告 将这两个包都识别为该活动的一部分。
冒充利用了在匆忙审查依赖时看起来合理的名称。发布者账号 dtolney 与 Rust 维护者 David Tolnay (@dtolnay) 使用的 dtolnay 账号仅差一个字母。包元数据虚假地将 Tolnay 列为作者,并指向他 GitHub 账号下不存在的仓库。现有证据将 Tolnay 识别为冒充目标,没有迹象表明他参与了该发布。
恶意包还复制了真实的 proc-macro2 的源代码。该选择使得在新增的构建脚本在后台运行时,依赖的构建仍能正常工作。SafeDep 发现 arrayref 本身保留了熟悉的宏实现;重要的更改只是 Cargo.toml 中的一条依赖项。Cargo 构建会声明非可选依赖,即使父 crate 从未调用它们。 (safedep.io)
负载与构建脱离
proc-macro1 的构建脚本从 base64 片段重建其服务器地址,以避免在源码中出现明显可见的 URL。该脚本通过 TLS 下载特定架构的二进制文件,然后将其以与构建脱离的方式启动。在 Unix 上,它写入并运行 /tmp/rust-setup。在 Windows 上,它在临时目录中创建 PowerShell 和 VBScript 启动器,将它们隐藏启动并放弃子进程,以便编译器无需等待该子进程结束。 (safedep.io)
SafeDep 发布了相关文件哈希和两个网络指标:在端口 9089 和 443 上的已中和主机 23[.]254[.]165[.]112。其分析确定了下载器的执行方式,但并未确定二阶段负载在启动后做了什么,也未说明有多少系统运行了该负载。
在 8 月 20 日 构建解析到 arrayref 0.3.10 的团队,应在锁文件和构建日志中搜索该确切版本及 proc-macro1 1.0.107。还应在构建主机上检查 Unix 的 /tmp/rust-setup、Windows 的 rust-setup.ps1 和 rust-setup-launch.vbs,以及与发布的网络指标的连接。一旦成功编译并不能清除主机;被复制的库代码就是为了让构建成功而设计的。
撤回安全版本制造了诱饵
据 SafeDep 和 RustSec 报告,控制 arrayref 的账号撤回了版本 0.3.5 到 0.3.9。Cargo 在所选发布版被 yank(撤回)时会警告用户,并建议迁移到仍可用的版本。当时,该路径指向了 0.3.10。首先发现该包的报告者表示,正是该警告导致了选中被投毒的版本。 (github.com)
该手法利用了开发者对真实包的信任,而不是等待有人在依赖名上打错字。arrayref 在 Rust GUI 的依赖图中位置较深,通过包括 tiny-skia、sctk-adwaita 和 winit 的包将其置于诸如 egui、eframe 和 iced 等框架之下。
SafeDep 统计 arrayref 的累积下载量约为 2.45 亿次,其中干净的 0.3.9 版本约占 1.52 亿次。这些数字反映的是多年的使用量,并不统计暴露于 0.3.10 的机器数量。相关的分母应为恶意发布可用期间完成的依赖解析和构建次数,已发布的分析并未提供该数据。 (safedep.io)
Datta 的预安装押注再次受考验
Datta 构建 SafeDep 的判断是,包安全必须移到执行之前。SafeDep 表示其 package firewall 可以位于公共注册表与开发者机器、CI 运行器或 AI 编码代理之间,在安装或构建脚本运行之前阻止某个依赖。SafeDep 还维护用于依赖审查和包拦截的开源工具。以上均为公司对其控制手段的主张,而非其软件阻止了这次特定 Rust 事件的证据。 (safedep.io)
竞争对手也在同一执行点销售控制产品。Endor Labs 在五月推出了 Package Firewall,而 Socket 在其扩展行为包分析和拦截产品的同时公布了以 10 亿美元估值完成的 6000 万美元 C 轮融资。
arrayref 的被入侵事件将 SafeDep 关于执行前防护的论点带到了 Rust 生态:当攻击者能够发布在应用存在之前就执行代码时,包信誉和一次干净的应用构建几乎无法提供保护。
此次活动将显然被入侵的 droundy 维护者账号与另一个用于冒充的 dtolney 账号配合使用,利用一个受信任的包和一个看似合理的依赖将代码引入 Cargo 构建。Datta 的押注是,开发者愿意为一种能够在代码运行之前做出决定的控制付费。