10 月 19 日 12:47 至 14:21(UTC),OVHcloud 官方 CLI 的五个历史版本安装包被换成会偷密钥的构建,在 GitHub release 页面挂了 94 分钟。源码没动、tag 没动、CI 没动——攻击者只替换了已发布 release 上挂的二进制文件。
事件概述
受影响版本为 v0.11.0 至 v0.15.0。攻击者用贡献者账号 HassenBF 走普通 Releases API:没推 tag,没触发 Actions,上传的是工作站上带未提交改动的 Go 构建产物。12:47 先换 v0.15.0,12:57 至 13:12 再替换 checksums.txt 与其余版本——校验和一起被换掉,对着官方校验和核对的做法完全失效。
发现问题的不是厂商:13:50,一个下游用户的 CI 固定了 v0.15.0 的 SHA-256,哈希不匹配导致构建失败,随后在 issue #300 贴出 go version -m 结果。14:21 全部被换文件被删除,当晚发布干净且不可变的 v0.16.0。
技术细节
根因是 GitHub 的 release immutability 没开。该选项 2025 年 10 月已普遍可用,开启后无法删除并重传已发布 release 的附件;未开启时附件可被替换而下载 URL 不变。于是出现空档:流水线是干净的,用户拿到的二进制不是。
识别手法值得记住:用 go version -m 看二进制,被换的模块行是伪版本 v0.15.1-0.20261013083505-5ead8ef9b43d+dirty,记录提交 5ead8ef,而 v0.15.0 的 tag 指向 760fd72。别把「带 +dirty 就是恶意」当规则——OVHcloud 自己的干净 v0.16.0 也标着 +dirty。
躲过一劫的路径很具体:Homebrew cask 固定了原始 SHA-256,直接拒绝安装;go install 与源码构建的 tag 仍指向 760fd72;Docker 镜像 latest 停在 9 月 21 日。中招的是执行官方 install.sh(不校验哈希)、从 release 页下 tar 包、CI 不固定哈希与 CLI 自升级。被换的是 macOS 双架构、Linux 双架构与 Windows x86_64 六类包。
影响评估
载荷没被留存,目前没人分析过样本。OVHcloud CEO Klaba 说质量很差但「能走完全程」,真正的风险不在那 94 分钟,而在跑过 CLI 的机器:~/.ovh.conf 里的云 API 凭证、SSH 私钥、token。管云的命令行本身就是身份工具。
归因要留余地。OpenSourceMalware 把该账号与 GlassWorm 关联,但标注为推断。可核实的是账号早在 2026 年 3 月 5 日就被控制,比换包早 228 天。同不同一拨人,没有直接证据。本次事件无 CVE。
修复建议
- 自查窗口:10 月 19 日 12:47 至 14:21 UTC 之间是否有主机或 CI 装过、升级过 ovhcloud CLI。
- 命中或无法判断:换一台机器,轮换原机器可读的全部密钥(OVH API 凭证、SSH 私钥、云 token、CI secret),装 v0.16.0 并用 gh release verify-asset 校验。
- 工程侧:CI 与安装脚本固定 SHA-256;发布侧开启 release immutability 与 attestation;能 go install 或源码构建就别下 tar 包。
- 推广一层:判别标准只有一个——安装过程有没有独立校验哈希;只信「最新版」,等于把安全边界交给分发通道。