Supply chain attack on arrayref

2026-08-20 37 预计阅读时间: 1 分钟
来源: blog.rust-lang.org AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:10 分钟

{"title_zh":"arrayref 供应链事件复盘:Rust 项目如何排查恶意 crate","body_zh":"# arrayref 供应链事件复盘:Rust 项目如何排查恶意 crate\n\n这起事件展示了 Rust 供应链攻击的一条现实路径:攻击者不必直接修改业务代码,只要控制维护者账号或开发环境,重新发布一个看似正常的热门 crate,再通过依赖引入带恶意 build.rs 的包,就可能在编译阶段执行下载载荷等操作。根据事件通报,恶意版本已经从 crates.io 删除,相关账号也已被锁定;使用 Rust 的团队仍需检查本地缓存、锁文件、构建日志和产物。\n\n## 攻击为什么能在编译时发生\n\nRust crate 可以包含构建脚本 build.rs。Cargo 编译依赖时会执行它,因此构建脚本拥有构建用户可用的文件、网络和环境变量权限。正常项目会用它探测系统库或生成绑定,但被篡改后,它也可能下载并运行额外载荷。\n\n本次通报涉及这些恶意版本:\n\n- append-only-vec@0.1.9\n- arrayref@0.3.10\n- internment@0.8.7\n- proc-macro1proc-macro-enaovinearonearonenaotinymember 的任意版本\n\n值得注意的是,被删除或 yanked 并不等于风险自动消失。.crate 文件可能仍留在开发机、CI runner、镜像层或私有代理缓存中;已有的 Cargo.lock、构建产物和被窃取的凭据也不会随上游处置自动恢复安全。\n\n## 先查缓存,再查依赖图\n\n可以先执行下面的命令检查当前用户的 Cargo registry 缓存:\n\nbash\nfind \"${CARGO_HOME:-$HOME/.cargo}/registry/cache\" -type f \\\n \( -name 'append-only-vec-0.1.9.crate' \\\n -o -name 'arrayref-0.3.10.crate' \\\n -o -name 'internment-0.8.7.crate' \\\n -o -name 'proc-macro1-*.crate' \\\n -o -name 'proc-macro-en-*.crate' \\\n -o -name 'aovine-*.crate' \\\n -o -name 'arone-*.crate' \\\n -o -name 'aronenao-*.crate' \\\n -o -name 'tinymember-*.crate' \) -print\n\n\n命中只说明包曾被下载,不足以证明恶意代码已经执行;没有命中也不能覆盖其他用户目录、容器缓存或远端 CI。随后应在每个 Rust 仓库中检查锁文件和解析后的依赖图:\n\nbash\nrg -n 'name = \"(append-only-vec|arrayref|internment|proc-macro1|proc-macro-en|aovine|arone|aronenao|tinymember)\"' Cargo.lock\n\ncargo tree -e all | rg 'append-only-vec v0\\.1\\.9|arrayref v0\\.3\\.10|internment v0\\.8\\.7|proc-macro1|proc-macro-en|aovine|arone|aronenao|tinymember'\n\n\n对 workspace,最好从根目录运行,并检查历史提交中的锁文件,因为当前分支没有命中不代表某次发布构建未使用过相关版本。\n\n## 命中后的处置顺序\n\n发现命中时,不要只删除缓存并重新编译。更稳妥的处置包括:\n\n1. 立即隔离对应开发机或 CI runner,暂停使用其产物。\n2. 保存 Cargo.lock、构建日志、网络日志和缓存文件哈希,供后续调查。\n3. 在可信环境中更新到不受影响的版本,并重新生成、审查锁文件。\n4. 清理 Cargo 缓存、CI 缓存和可能包含恶意层的容器镜像。\n5. 轮换构建环境可读取的 crates.io token、Git 凭据、云密钥、签名密钥和发布凭据。\n6. 从干净、受控的构建环境重新产出并签名制品。\n\n例如,可以先在隔离副本中精确更新依赖,再验证锁文件:\n\nbash\n# 在确认目标安全版本后替换 <SAFE_VERSION>\ncargo update -p arrayref --precise <SAFE_VERSION>\ncargo tree -i arrayref\ngit diff -- Cargo.lock\n\n\n这里不应盲目填写版本号。应以 crates.io 当前状态、项目兼容性测试和团队批准的版本清单为准。\n\n## 把一次排查变成长期控制\n\n这类事件说明,仅依赖 yanking 和人工通知不够。团队可以在 CI 中固定 Cargo.lock,对应用程序使用 cargo build --locked,并引入 cargo-deny 等工具审计禁用 crate、来源和许可证。构建任务还应采用最小权限:默认禁止不必要的外网访问,不向普通编译步骤注入发布密钥,并使用短生命周期凭据。\n\n最后保留一份可执行清单:扫描所有开发机与 runner,搜索当前及历史锁文件,核查构建期网络连接,轮换可能暴露的凭据,从可信环境重建制品。供应链事件的边界不止是“依赖版本是否出现”,还包括该版本在哪里执行过,以及执行时能够访问什么。","title_en":"The arrayref Supply Chain Incident: How to Audit Rust Builds for Malicious Crates","body_en":"# The arrayref Supply Chain Incident: How to Audit Rust Builds for Malicious Crates\n\nThis incident illustrates a practical Rust supply chain attack path: compromise a maintainer account or workstation, republish a trusted crate with a new dependency, and let a malicious build.rs execute during compilation. The reported packages have been removed and the affected account locked, but downstream teams still need to inspect caches, lockfiles, CI systems, credentials, and previously produced artifacts.\n\n## Why build scripts expand the blast radius\n\nCargo runs a crate's build.rs while compiling dependencies. Legitimate build scripts detect native libraries or generate bindings, but they execute with the permissions of the build user. A compromised script can therefore read available environment variables, access files, and make network requests unless the build environment restricts those capabilities.\n\nThe incident report identifies these malicious releases:\n\n- append-only-vec@0.1.9\n- arrayref@0.3.10\n- internment@0.8.7\n- Any version of proc-macro1, proc-macro-en, aovine, arone, aronenao, or tinymember\n\nDeletion or yanking limits future resolution, but it does not erase downloaded archives, container layers, private registry mirrors, build logs, or credentials exposed during an earlier build.\n\n## Check local caches and resolved dependencies\n\nStart by searching the Cargo registry cache for the reported archives:\n\nbash\nfind \"${CARGO_HOME:-$HOME/.cargo}/registry/cache\" -type f \\\n \( -name 'append-only-vec-0.1.9.crate' \\\n -o -name 'arrayref-0.3.10.crate' \\\n -o -name 'internment-0.8.7.crate' \\\n -o -name 'proc-macro1-*.crate' \\\n -o -name 'proc-macro-en-*.crate' \\\n -o -name 'aovine-*.crate' \\\n -o -name 'arone-*.crate' \\\n -o -name 'aronenao-*.crate' \\\n -o -name 'tinymember-*.crate' \) -print\n\n\nA match proves that an archive was downloaded, not that its payload executed. No match only clears that specific cache location; CI runners, containers, other user accounts, and registry proxies must be checked separately. In each repository, inspect both the lockfile and Cargo's resolved graph:\n\nbash\nrg -n 'name = \"(append-only-vec|arrayref|internment|proc-macro1|proc-macro-en|aovine|arone|aronenao|tinymember)\"' Cargo.lock\n\ncargo tree -e all | rg 'append-only-vec v0\\.1\\.9|arrayref v0\\.3\\.10|internment v0\\.8\\.7|proc-macro1|proc-macro-en|aovine|arone|aronenao|tinymember'\n\n\nRun these checks at the workspace root and search historical lockfiles as well. A clean current branch does not prove that an earlier release pipeline never resolved the affected versions.\n\n## Respond to a positive finding\n\nDo more than delete the cache. A defensible response is to isolate the workstation or runner, preserve lockfiles and logs, record hashes of suspicious archives, and stop distributing artifacts produced by that environment. Then update dependencies in a trusted environment, clear CI and container caches, rotate every credential visible to the build, and rebuild release artifacts from clean inputs.\n\nFor example, after independently confirming an approved safe version, update it precisely and review the resulting graph and lockfile diff:\n\nbash\n# Replace <SAFE_VERSION> only after verifying the approved release\ncargo update -p arrayref --precise <SAFE_VERSION>\ncargo tree -i arrayref\ngit diff -- Cargo.lock\n\n\nDo not guess the replacement version. Base that decision on the current registry state, compatibility tests, and your organization's approved dependency inventory.\n\n## Controls worth keeping after the incident\n\nApplications should commit Cargo.lock and build with cargo build --locked in CI. Tools such as cargo-deny can enforce crate bans and source policies, while restricted build networking reduces what a malicious build script can retrieve or exfiltrate. Build jobs should receive only short-lived, task-specific credentials; publishing and signing keys should not be present during ordinary dependency compilation.\n\nThe final review should answer four questions: where was the package downloaded, where was it built, what could that build environment access, and which artifacts came out of it? That scope is broader than a version check, but it is the difference between removing a dependency and actually containing a supply chain compromise.","seo_description_en":"Audit Rust projects for the malicious arrayref supply chain releases, inspect Cargo caches and lockfiles, rotate credentials, and rebuild safely."}


相关推荐