内容提要
Rust安全团队发现Miri会将所有环境变量存入target/目录,若该目录被GitHub Actions缓存,攻击者可通过PR读取缓存中的密钥。已发布修复,仅保留CARGO_*(除TOKEN)和OUT_DIR变量。建议检查CI配置、清除缓存并轮换密钥。
延伸解读
攻击路径与隐蔽性
攻击者只需曾成功合并过PR,即可在后续PR中触发CI,从缓存的target/目录读取环境变量中的密钥,再通过推送第二个提交覆盖痕迹。GitHub UI有时会隐藏被覆盖的提交,且CI日志和旧提交会在几个月后删除,导致此类攻击难以被察觉。
修复方案与适用范围
短期修复让Miri仅保留CARGO_*(排除CARGO_*_TOKEN)和OUT_DIR环境变量,该补丁可能尚未进入nightly。预计2026-09-22的nightly版本将包含修复。但Rust工具链不保证环境变量不会被复制到target/,构建脚本也可能将环境写入编译产物,因此不能依赖此修复作为通用防护。
自查与缓解建议
若CI使用actions/cache或swatinem/rust-cache缓存target/,且运行Miri,则可能受影响。建议检查GitHub Actions配置,清除缓存,并轮换可能泄露的密钥。即使不运行Miri,也应确保能写入公共缓存的任务无法访问密钥,避免缓存被污染。
Q&A
Miri 缓存导致 GitHub Actions 泄露密钥的根本原因是什么?
Miri 会将所有环境变量存储到 target/ 目录中,当该目录被 GitHub Actions 缓存时,攻击者可以通过 PR 读取缓存中的密钥。
攻击者如何利用这个漏洞窃取密钥?
攻击者可以打开 PR 触发 CI 运行,从缓存的 target/ 中提取信息,然后通过推送第二个提交来覆盖痕迹。GitHub 有时会隐藏被覆盖的提交,使得攻击难以检测。
Rust 安全团队发布的短期修复方案是什么?
短期修复是让 Miri 只保留 CARGO_* 环境变量(除了 CARGO_*_TOKEN)和 OUT_DIR。
如何判断自己的 GitHub Actions 设置是否受此漏洞影响?
如果你在 CI 中运行 Miri,并且使用了 env、target、actions/cache 或 swatinem/rust-cache,则可能受影响。
如果怀疑密钥已泄露,应该采取哪些紧急措施?
应清除缓存,并考虑轮换可能已泄露的密钥。
即使不使用 Miri,缓存 target/ 时需要注意什么?
确保能够写入公共缓存的任务不能访问密钥。如果缓存 target/,要确保调用 cargo 的进程没有可用的密钥。