[release-branch.go1.25] cmd/go: reject sumdb response lacking module hash Report an error when a sumdb /lookup/ request does not include a hash for the requested module, rather than silently proceeding. Previously, we would verify that a returned sum matched the expected module hash, but did not verify that the response contained a sum. This permits a malicous proxy to serve a corrupted module along with a valid-but-irrelevant sumdb response for some other module. We now ensure that the sumdb response contains a valid hash for the module we are validating. Thanks to Mundur (https://github.com/M0nd0R) for reporting this issue. Fixes CVE-2026-42501 Updates #79070 Fixes #79072 Change-Id: I7d9a367deb237aa70cade2434495998f6a6a6964 Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/4340 Reviewed-by: Nicholas Husin <husin@google.com> Reviewed-by: Neal Patel <nealpatel@google.com> Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/4421 Reviewed-by: Damien Neil <dneil@google.com> Reviewed-on: https://go-review.googlesource.com/c/go/+/775161 TryBot-Bypass: Gopher Robot <gobot@golang.org> Reviewed-by: Michael Pratt <mpratt@google.com> Auto-Submit: Gopher Robot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
diff --git a/src/cmd/go/internal/modfetch/fetch.go b/src/cmd/go/internal/modfetch/fetch.go index 5d310cc..41e02e7 100644 --- a/src/cmd/go/internal/modfetch/fetch.go +++ b/src/cmd/go/internal/modfetch/fetch.go
@@ -851,7 +851,7 @@ return module.VersionError(modWithoutSuffix, fmt.Errorf("verifying %s: checksum mismatch\n\tdownloaded: %v\n\t%s: %v"+sumdbMismatch, noun, h, db, line[len(prefix)-len("h1:"):])) } } - return nil + return module.VersionError(modWithoutSuffix, fmt.Errorf("verifying %s: checksum missing from sumdb response"+sumdbAbsent, noun)) } // Sum returns the checksum for the downloaded copy of the given module, @@ -1062,6 +1062,19 @@ For more information, see 'go help module-auth'. ` +const sumdbAbsent = ` + +SECURITY ERROR +This download does NOT match one reported by the checksum server. +The checksum server has provided checksums, but the checksums do +not contain an entry for the download. +The checksum server may be malfunctioning, or an attacker may have +intercepted the checksum request. +The download cannot be verified. + +For more information, see 'go help module-auth'. +` + const hashVersionMismatch = ` SECURITY WARNING
diff --git a/src/cmd/go/proxy_test.go b/src/cmd/go/proxy_test.go index 5ff8136..2a8bace 100644 --- a/src/cmd/go/proxy_test.go +++ b/src/cmd/go/proxy_test.go
@@ -172,6 +172,23 @@ return } + // Request for $GOPROXY/sumdb-redirect/module@version:/lookup/... + // performs a lookup for module@version rather than the requested module. + if strings.HasPrefix(path, "sumdb-redirect/") { + redirect, rest, ok := strings.Cut(path[len("sumdb-redirect"):], ":") + if !ok { + w.WriteHeader(500) + return + } + if strings.HasPrefix(rest, "/lookup/") { + r.URL.Path = "/lookup" + redirect + } else { + r.URL.Path = rest + } + sumdbServer.ServeHTTP(w, r) + return + } + // Request for $GOPROXY/redirect/<count>/... goes to redirects. if strings.HasPrefix(path, "redirect/") { path = path[len("redirect/"):]
diff --git a/src/cmd/go/testdata/script/mod_sum_absent.txt b/src/cmd/go/testdata/script/mod_sum_absent.txt new file mode 100644 index 0000000..c2dd814 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_sum_absent.txt
@@ -0,0 +1,17 @@ +# When the sumdb returns a response which does not +# include a sum for the requested module, +# we should report an error. +# Verifies CVE-2026-42501. +env sumdb=$GOSUMDB +env proxy=$GOPROXY +env GOPROXY GONOPROXY GOSUMDB GONOSUMDB + +# /sumdb-redirect/ causes the sumdb to return /lookup/ responses +# for rsc.io/quote@v1.0.0, not for the requested module. +env GOSUMDB=$sumdb' '$proxy/sumdb-redirect/rsc.io/quote@v1.0.0: + +! go get rsc.io/fortune@v1.0.0 +stderr 'SECURITY ERROR' +! grep rsc.io go.sum +-- go.mod -- +module m