Bump golang.org/x/mod to v0.40.0 for CVE-2026-56864 and CVE-2026-56865 - #797
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
Bumps Go tooling dependencies to address two x/mod vulnerabilities.
Changes:
- Updates
x/modto v0.40.0. - Transitively updates
x/toolsandx/net. - Refreshes dependency checksums; the CI workspace checksum remains incomplete.
Tip
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
go/go.mod |
Updates Go tooling dependencies. |
go/go.sum |
Refreshes module checksums. |
go.work.sum |
Updates workspace checksums. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Trivy (Go SDK) fails on both advisories against the v0.38.0 the module carries as an indirect dependency. Both are fixed in v0.40.0 — v0.39.0 carries neither fix, so this is the smallest move that clears the gate. The dependency reaches the graph only through the oapi-codegen tool directive, and only as golang.org/x/mod/modfile. Neither vulnerable package is imported anywhere in the module: `go list -deps all` resolves four x/mod packages — lazyregexp, semver, module, modfile — and sumdb and sumdb/tlog are not among them. MVS carries x/tools v0.48.0 -> v0.49.0 along with it, because x/mod v0.40.0 requires it. No generated file moves; go-check-generated-drift regenerates the client and diffs clean. go.work.sum gains the hashes the workspace needs to verify the new selection. Its x/text v0.41.0 h1: line is only reached on a cold module cache — the generator needs it when re-emitting the client — so it was found by rebuilding under an empty GOMODCACHE, the way CI runs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Trivy (Go SDK) fails on
golang.org/x/mod v0.38.0, whichgo/go.modcarries asan indirect dependency. This bumps it to v0.40.0. Two manifest lines and their
go.sum/go.work.sumhashes; nothing else moves.The two advisories, and why v0.39.0 is not enough
golang.org/x/mod/sumdb(Client.Lookup)golang.org/x/mod/sumdb/tlog(tileHashReader.ReadHashes)Source: the OSV API (
https://api.osv.dev/v1/vulns/GO-2026-6179,…/GO-2026-6180).Both records give
golang.org/x/moda single affected range of[0, 0.40.0)—introduced at
0, fixed at0.40.0. Trivy independently agrees: its failing runprints
0.40.0in the Fixed Version column for both.So the smaller move is not available. v0.39.0 carries neither fix and would
leave the gate red; v0.40.0 is the first version that clears both.
Reachability: code-generation toolchain only, and not even there
Worth stating plainly, because the CVSS reads alarming and the actual exposure is
narrow in two independent ways.
1. It is not in the published module's runtime surface.
golang.org/x/modenters the graph solely through the
tooldirective at the bottom ofgo/go.mod:go list -deps ./...— the packages consumers actually compile — returns nox/modpackage at all. Nothing an SDK consumer imports links it.2. The vulnerable packages are not imported by anything, including the
generator. Both advisories are scoped to
sumdbandsumdb/tlog. The wholemodule graph resolves exactly four
x/modpackages:modfileparsesgo.modfiles; the sumdb client is a separate package thatnothing here links. The threat model behind these CVEs — a malicious GOPROXY or
GOSUMDB tampering with module fetches — is
cmd/go's, and it is addressed for usby the toolchain, not by this dependency.
This is therefore a manifest-hygiene fix, not an exploitable-path fix. It is
still worth landing: the gate is a merge blocker for five open PRs, and arguing
reachability at every scan is more expensive than moving one line.
Why govulncheck and Trivy disagree, and which one to believe here
govulncheck ./...is byte-identical before and after this change — I diffed thetwo runs and they match exactly. It never reported these CVEs in the first place,
so it cannot confirm their removal:
Both runs report the same 4 stdlib findings from the local
go1.26.5toolchain(all fixed in
go1.26.6, all unrelated to this change), plus "2 vulnerabilitiesin modules you require, but your code doesn't appear to call these" — and even
those two are stdlib, per
-show verbose. Scanning the generator's own call graph(
govulncheck github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen) likewisereports nothing from
x/mod.That is not govulncheck failing; it is govulncheck being right. It is call-graph
aware, so an unreachable
sumdbis correctly silent — which is the same findingas the section above, arrived at by a second instrument. Trivy's
fsscan readsgo.modas a manifest with no reachability analysis, so it flags every moduleversion in the graph. Trivy is the gate, so Trivy is the check that has to go
green, and govulncheck is reported here only so the "before/after" is not
mistaken for evidence it cannot supply.
Trivy, before and after
A local green proves nothing unless the same DB is shown to catch the bug, so
here is the matched pair against one freshly downloaded DB (
UpdatedAt 2026-08-19T13:00:00Z), with the base manifest taken fromorigin/main:Zero generated churn
The repo's pattern is to bump the leaf tool-dep rather than the
oapi-codegengenerator, precisely so no emitted file moves. It holds here:
Confirmed more strongly than by
git statusalone —make go-check-generated-driftregenerates
client.gen.gointo a temp directory under the new toolchain anddiffs it: no drift. The generator emits identical bytes.
Two notes on the diff being three files rather than two:
x/toolsv0.48.0 → v0.49.0 is MVS-forced, not a second bump.go mod graphhas the edge
golang.org/x/mod@v0.40.0 golang.org/x/tools@v0.49.0; x/mod v0.40.0requires it, so the selection is not optional.
go.work.sumis a real consequence, not scan residue. I checked by revertingto pristine
origin/mainand runningmake go-check: the tree stayed clean. Underthe bump the same command rewrites
go.work.sum, so it is committed —scripts/assert-lockfiles-unchangedcoversgo.work.sumand would otherwise failthe first CI job to build Go.
A warm module cache hid one line of that, and CI caught it. The first push
committed a
go.work.sumgenerated on this machine, wheremake go-checkconverged across two runs. CI's Go Tests job still failed the guard: on a cold
cache the generated-client drift check needs
golang.org/x/text v0.41.0 h1:(x/tools v0.49.0 pulls x/text v0.41.0, and re-emitting the client links it),
while a warm cache had it already extracted and never recorded the hash. Rerunning
every step of that job under an empty
GOMODCACHEreproduced the failure exactly,and the amended commit passes the same cold sequence with
Dependency manifests match the committed tree.Worth naming rather than quietlyamending: local convergence is not a cold-cache proof, and the guard is what
distinguished them.
go.sumis tidied —origin/mainis tidy (go mod tidyon it is a no-op), sothis keeps that property rather than leaving superseded
h1:lines behind.Why this is its own PR: four green Security checks that are stale, not clean
The advisories were published 2026-08-13 but only entered Trivy's DB on
2026-08-19, which puts a hard line through that day's CI:
Nothing about #794 introduced this. Its run is simply the first one on the far
side of the DB update — the failure names
golang.org/x/mod v0.38.0, which everyone of those branches carries identically from
main.The four greens are stale, not clean, and will go red on any re-run. I can
narrow the window further from an accident: my own machine's Trivy DB was built
2026-08-19T00:49:40Z, and scanning the unfixed base manifest with it returneda confident
Total: 0. Refetching the DB (built13:00Z) turned the identicalinput red. So the advisory landed in Trivy's DB between 06:43Z and 13:00Z —
after all four greens, before #794's red — and a stale DB reproduces the false
green on demand.
Hence a separate, Go-only PR: fixing this inside any one of the five would make
that PR's diff carry an unrelated dependency bump, and would still leave the
other four blocked.
Verification
All gates run with
REAL_EXIT=$?written into a log and grepped back, not via; echoafter a pipe.LC_ALL=C make go-checkREAL_EXIT=0make go-check-driftREAL_EXIT=0— 250/250 operations, 100%make go-check-wrapper-driftREAL_EXIT=0— 92 pairs, 1252 generated fieldsmake go-check-generated-driftREAL_EXIT=0— no driftscripts/assert-lockfiles-unchanged --verify-cleanREAL_EXIT=0(post-commit)REAL_EXIT=0The API Compatibility job (
apidiff -m, added in #776) runs on this PR; adependency bump touching no source file should be API-identical, and that job is
the proof rather than my assertion.