Go 模块供应链:恶意 GOPROXY 伪造 sumdb 瓦片绕过 GOSUMDB
2026 年 8 月 Go 官方修复了一对关联漏洞,编号 CVE-2026-56864 / CVE-2026-56865(对应 GO-2026-6180 / GO-2026-6179,CVSS 8.4)。一句话概括:恶意 GOPROXY 可以伪造至多两个 sumdb 瓦片,绕过 GOSUMDB 校验,把攻击者控制的模块内容悄悄写进本地模块缓存,而且透明度日志完全察觉不到。这属于实打实的供应链投毒路径。
这个漏洞骗过了什么
正常流程里,go 拉模块要走两层校验:
go.sum里的哈希校验模块内容;- GOSUMDB(默认
sum.golang.org)的透明度日志校验当前版本是否真的被发布过。
攻击的关键在瓦片(tile)结构。sumdb 的日志按瓦片组织,客户端通过瓦片验证模块哈希是否在日志里。CVE-2026-56865 的问题是:瓦片与父瓦片之间的校验没做对。恶意 GOPROXY 构造出伪造的瓦片对,客户端校验时以为哈希落在日志里了,实际内容完全是攻击者给的。
结果就是:一份「看起来经过 sumdb 背书」的恶意模块被缓存下来,go.sum 里也对得上,常规排查根本看不出来。修复方式是让每个瓦片都去校验自己的父瓦片,切断这条伪造链。
什么条件下才会中招
不是用了 Go 就危险,三个条件要同时成立:
- 受影响工具链版本:cmd/go
< 1.25.13、1.26.0-0 ~ <1.26.6、1.27.0-0 ~ <1.27.0-rc.3;另外golang.org/x/mod < 0.40.0。 - GOPROXY 指向了攻击者可控制/可篡改的代理。默认
proxy.golang.org本身不受影响;国内常见的七牛、阿里镜像如果没被攻陷也不在攻击面内,但凡是自建私有代理或某公网镜像被入侵,就落入风险。 - 有人实际执行了模块拉取:
go mod tidy、go get、go build触发取瓦片。
一句话:绝大多数只依赖官方代理、版本又新的环境,实际风险很低。真正要紧张的是自建 GOPROXY 的企业——那本来就是信任链上的单点。
自查与修复
先确认是否受影响,官方给了一条命令:
rm -r go.sum go.work.sum vendor/ && go mod tidy
如果重新生成后 go.sum 内容变了,说明之前的校验结果可能不可信,需要逐条核对依赖来源。然后升级工具链到 1.25.13 / 1.26.6 / 1.27.0-rc.3 以上任一轨道。
CI 与团队层面怎么降风险
- 锁定 GOPROXY 与 GOSUMDB:别让每个开发者的
~/.config/go/env各自为政,统一GOPROXY=https://proxy.golang.org,direct并GOFLAGS=-mod=mod,镜像也要固定你信任的那一家。 go.sum进版本库且强制校验:别图省事删掉它,GOFLAGS=-mod=readonly让多写一字节都报错。- 私有模块走
GONOSUMDB/GOPRIVATE白名单,而不是靠关掉全局 sumdb 来省事——关全局等于把这条防线让给代理。 - 缓存做周期性重建:CI 里定期清掉 GOMODCACHE 重新拉,配合依赖审计(govulncheck)能早发现异常。
这个洞本质上是「把透明度日志的信任交给了传输链路」的经典反例。对普通开发者,升级版本就够了;对自建代理的团队,得把代理本身当成高价值资产来管。如果你们业务还在用老工具链 + 私有 GOPROXY 的组合,建议把这个修复排进本周发布计划。