你以为换个 cargo 源只是配置问题?今天 Cargo 的 URL 标准化 bug 把三千多个仓库的 token 彻底漏了

Cargo 的 1.68 到 1.95 有一个 URL 标准化逻辑 bug:对稀疏索引(sparse index)源,它错误地剥离了 .git 后缀。攻击者如果同时满足两个条件——在同一个域名下既发布了一个 crate,又托管了一个带 .git 后缀的路径——就能截获受害者的认证令牌。

Rust 官方在 1.96.0 里修了它。但因为 Rust 更新频率,这个 bug 悄悄在三千多个发布版本里存活了快两年。


漏洞是怎么工作的

Cargo 在发布和安装依赖时,需要从注册表(Registry)拉取索引。稀疏索引协议(sparse index)是 2022 年引入的,让 Cargo 直接通过 https://Index.Crates.io 这类地址查询包信息,而不需要克隆整个 git 仓库。

问题出在 URL 标准化这一步。Cargo 会在发出请求前,对目标 URL 做规范化处理——比如把 https://my-registry.example.com/api/v1/crates/foohttps://my-registry.example.com/api/v1/crates/foo.git 当作同一个地址处理。

攻击者的攻击路径是这样的:

  1. 注册一个与目标公司同域名的包
    比如目标公司内部 registry 是 https://crates.mycompany.com,攻击者注册一个 crates.mycompany.com/foo 的公开包。

  2. 在同一域名下托管一个带 .git 的路径
    攻击者在自己的服务器上放置一个 https://crates.mycompany.com/some-package.git/ 路径。

  3. 利用 Cargo 的错误标准化
    当受害者安装了攻击者发布的包,Cargo 在处理某些请求时,会把本该发往官方 registry 的认证令牌,通过这个 .git 路径泄露给攻击者服务器。

本质上,这是路径混淆——Cargo 把「发给我自己 registry 的令牌」错误地发到了攻击者控制的地址。


两个 CVE,一个比一个有意思

Rust 1.96.0 修了两个安全漏洞:

CVE-2026-5222(低危)
就是这个 URL 标准化 bug。修复方式是:.git 后缀剥离现在只对 git-protocol 类型的注册表生效,稀疏索引不受影响。

CVE-2026-5223(中危)
tarball 符号链接提取问题。Cargo 在解压依赖的 tar.gz 时,如果没有正确验证符号链接的目标路径,攻击者可以构造一个指向仓库外的文件路径,让 Cargo 在提取时覆盖系统文件或读取敏感文件。


你的 Cargo 在哪个版本?

最简单的方式:

cargo –version

如果是 1.68 到 1.95 之间的任何版本,都需要更新。这涵盖了从 2023年4月 到 2026年9月 的所有 Rust 版本——基本上如果你没有定期更新工具链,很可能中招。


如果你用的是 crates.io 官方源

好消息是,这个漏洞不直接影响 crates.io 用户。官方的索引托管在 GitHub Pages 上,不存在攻击者控制同域名路径的情况。

但如果你用的是私有 registry(比如公司内部的 Cargo 源),风险就真实存在了。特别是如果你允许从非官方源发布包,或者 registry 和其他服务共享域名。


三步检查清单

  1. 查版本
    cargo –version
    如果是 1.95.0 或以下,立刻 rustup update stable。

  2. 查私有源配置
    cat ~/.cargo/config.toml
    确认你用的 registry 地址是否与公司其他服务共享域名。

  3. 查 CI 日志
    如果你的 CI 在每次构建时自动调用 cargo install 或 cargo update,确认 CI 环境里的 Rust 版本是最新的。很多 CI 镜像会预装旧版本 Rust 但不自动更新。


这个 bug 的狡猾之处在于:它不要求攻击者黑进你的系统,只需要在同一个域名下注册一个公开包。你可能永远不知道自己的 token 什么时候漏了——Cargo 不会报错,请求看起来完全正常。

定期更新 Rust 工具链,不只是为了性能和新特性,也是最简单、最便宜的安全防线。

评论区

0 条评论

登录后可评论。

铁锈·Rust工具链 16 阅读