sec(deps): bump the build toolchain to go1.26.6 (backend#1972) - #500
Merged
Conversation
`govulncheck` reports four CALLED stdlib vulnerabilities on go1.26.5 — reached
from this module's own code, not merely present in the dependency graph:
GO-2026-6218 net/url quadratic complexity in resolvePath
GO-2026-6090 crypto/tls post-handshake message flood
GO-2026-5972 encoding/asn1 unbounded recursion depth
GO-2026-5026 net/http x/net/idna Punycode label handling
All four are fixed in go1.26.6, and none needs a code or dependency change.
Every workflow resolves Go through `go-version-file: go.mod`, so this one line
moves build.yml, golangci.yml, e2e.yml, mutation.yml, release.yml and
chart-drift.yml together.
`go 1.26.0` is deliberately untouched — that is the language floor, not the
toolchain, and .golangci.yml's `go: "1.26"` tracks it. Only the compiler moves.
## Evidence, on a real toolchain rather than from release notes
GOTOOLCHAIN=auto fetched go1.26.6 and used it:
go version go1.26.6 darwin/amd64 (downloaded on demand)
go build ./... exit 0
go vet ./... exit 0
go test ./... exit 0 (all packages ok)
govulncheck ./... exit 0 "No vulnerabilities found."
Counterfactual, so the bump is demonstrably what fixed it rather than something
incidental — reverted the single line and re-ran the same binary:
toolchain go1.26.5 -> exit 3, 4 vulnerabilities (the four above)
toolchain go1.26.6 -> exit 0, none
Exit codes read explicitly: govulncheck exits 3 on findings, so "looks clean"
in the output is not the same as passing.
## What is NOT in this PR
Making `govulncheck` a required status check. It is red-on-main today and the
prod promotion merged straight past it, which is the actual defect — filed as
backend#1972. It must be armed only AFTER this reaches `main`: adding the
context while main is still on go1.26.5 would block every release-train
promotion on the branch the train has to merge into.
Fix first, arm second.
The version-bump gate caught what I left out: v0.10.6 is already released, and this PR changes `go.mod` — a published path — so the binary the train ships would differ from the one v0.10.6 tagged. The gate's own wording is the reason this matters: the train reads VERSION and cuts the tag from it, never bumping for you, so a stale file does not fail here — it fails the next prod hop, days later, on somebody else (backend#1561). Patch bump: stdlib security fixes via go1.26.6, no behaviour or API change.
shujaatTracebloc
approved these changes
Aug 14, 2026
6 tasks
LukasWodka
added a commit
that referenced
this pull request
Aug 14, 2026
…hat keeps it (backend#1972) (#501) * ci(vulncheck): one declaration for the govulncheck pin, and a check that keeps it (backend#1972) The version lived in THREE places -- build.yml's job, vulncheck.yml's job, and GOVULNCHECK_VERSION in the Makefile -- held in step by a comment reading "keep the job in lockstep". All three happened to read v1.1.4, which is exactly what made it look fine. Two copies kept in sync by a request is not a mechanism. Both workflows now run `make vulncheck`, so the Makefile is the single declaration, and a green `make ci` locally cannot disagree with the PR gate about which govulncheck ran -- the same reasoning already applied to lint-full/GOLANGCI_LINT_VERSION. The "keep in lockstep" comment is replaced by a machine check rather than deleted: scripts/check-tool-pins.sh PARSES GOVULNCHECK_VERSION out of the Makefile and fails the Lint job if any workflow hardcodes that module with an @Version. The guard holds no version of its own, so it cannot agree with itself while disagreeing with reality. Mutation-proved, anchors asserted: reintroduce `go install ...govulncheck@v1.1.4` in build.yml -> exit 1, names file and line delete GOVULNCHECK_VERSION from the Makefile -> exit 2, refuses to report clean run from an unrelated cwd -> still correct (cd's to its root) The two jobs still differ, deliberately, and now ONLY in the ref: vulncheck.yml checks out develop on a schedule, build.yml judges the PR head. That difference is stated in the file instead of being buried in duplicated steps. DRAFT until cli#500 lands. `govulncheck` is already red on develop -- go1.26.5 carries 4 reachable stdlib CVEs -- so this branch inherits that failure. Verified locally that the folded target reproduces it exactly: make vulncheck -> exit status 3, "affected by 4 vulnerabilities from the Go standard library", each "Fixed in: <pkg>@go1.26.6" which also independently confirms backend#1972's counterfactual. This PR does not change WHAT govulncheck finds, only where its version is declared. NOT in this PR, and both belong to the ticket rather than here: adding govulncheck to `main`'s required contexts (needs #500 on main first, plus the break-glass decision -- enforce_admins is true there and skip-fr-gate does not bypass a required check), and the same three-copies shape for GOLANGCI_LINT_VERSION, which TOOLS in the new guard is structured to take as a second row. The two actionlint SC2001 findings on build.yml are pre-existing on develop (verified against the unmodified base) and untouched here. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * ci(vulncheck): run the pin guard in make ci/check + fail it closed on grep errors Two Bugbot findings on the govulncheck single-declaration change (backend#1972): - check-tool-pins ran only in the CI Lint job, so a green local `make ci` / `make check` could disagree with the PR about a restated pin — the exact local/CI divergence the Makefile-as-entry-point exists to prevent. Add it to both aggregate targets, beside check-style/file-budget. - The workflow scan used `grep ... 2>/dev/null || true`, laundering a real grep error (rc>=2: unreadable tree, bad invocation) into an empty hit list and an unearned clean pass — the fail-open this guard was written against. Capture rc and fail closed on rc>=2, matching scan() in check-style.sh. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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.
govulncheckreports four CALLED stdlib vulnerabilities on go1.26.5 — reachedfrom this module's own code, not merely present in the dependency graph:
GO-2026-6218 net/url quadratic complexity in resolvePath
GO-2026-6090 crypto/tls post-handshake message flood
GO-2026-5972 encoding/asn1 unbounded recursion depth
GO-2026-5026 net/http x/net/idna Punycode label handling
All four are fixed in go1.26.6, and none needs a code or dependency change.
Every workflow resolves Go through
go-version-file: go.mod, so this one linemoves build.yml, golangci.yml, e2e.yml, mutation.yml, release.yml and
chart-drift.yml together.
go 1.26.0is deliberately untouched — that is the language floor, not thetoolchain, and .golangci.yml's
go: "1.26"tracks it. Only the compiler moves.Evidence, on a real toolchain rather than from release notes
GOTOOLCHAIN=auto fetched go1.26.6 and used it:
Counterfactual, so the bump is demonstrably what fixed it rather than something
incidental — reverted the single line and re-ran the same binary:
Exit codes read explicitly: govulncheck exits 3 on findings, so "looks clean"
in the output is not the same as passing.
What is NOT in this PR
Making
govulnchecka required status check. It is red-on-main today and theprod promotion merged straight past it, which is the actual defect — filed as
backend#1972. It must be armed only AFTER this reaches
main: adding thecontext while main is still on go1.26.5 would block every release-train
promotion on the branch the train has to merge into.
Fix first, arm second.
Note
Low Risk
Toolchain-only security patch with no logic or dependency changes; low blast radius beyond build/reproducibility.
Overview
Pins the Go build toolchain to
go1.26.6(fromgo1.26.5) and bumps VERSION to0.10.7. The language floorgo 1.26.0is unchanged.This addresses four stdlib issues that
govulncheckreports as reachable from this module (crypto/tls,encoding/asn1,net/http,net/url) with no application or dependency edits—CI and release builds already take Go fromgo-version-file: go.mod, so the toolchain line updates build, lint, e2e, mutation, release, and chart-drift workflows together.go.modcomments document the CVEs, call paths, and that makinggovulnchecka required check is intentionally deferred until after this lands onmain(backend#1972).Reviewed by Cursor Bugbot for commit 528ddfb. Bugbot is set up for automated code reviews on this repo. Configure here.