Skip to content

build: rebuild on Go 1.26.10 and x/net v0.60.0 (CVE-2026-78667, -78669, -97031) - #160

Merged
sylvesterdamgaard merged 2 commits into
mainfrom
claude/interesting-easley-b46fb1
Oct 20, 2026
Merged

sylvesterdamgaard merged 2 commits into
mainfrom
claude/interesting-easley-b46fb1

Conversation

@sylvesterdamgaard

Copy link
Copy Markdown
Contributor

Same code as 3.8.2, rebuilt on a patched toolchain. No behaviour change.

The v3.8.2 binaries were built by a floating go-version: '1.26', which resolved to 1.26.8 and shipped four HIGH denial-of-service findings that php-baseimages' pre-promotion Trivy gate rejects — so no php-base / php-fpm / php-cli / php-fpm-nginx tag has been published since 2026-10-08.

CVE Module Was Now
CVE-2026-78667 stdlib net/http (crafted Range headers) 1.26.8 1.26.10
CVE-2026-78669 stdlib net/http2 (excessive HTTP/2 SETTINGS frames) 1.26.8 1.26.10
CVE-2026-97031 stdlib crypto/tls (multiple ECH outer extension references) 1.26.8 1.26.10
CVE-2026-78669 golang.org/x/net HTTP/2 v0.58.0 v0.60.0

cbox-init serves HTTP on the metrics (:9090), readiness (:9091, bound 0.0.0.0) and management API ports, so none of these were dead code.

Changes

  • go.mod: toolchain go1.26.6 → go1.26.10 (stays on the 1.26 line). The language directive go 1.26.0 is untouched. The existing comment about the supply-chain gate is kept and updated to name the current pin.
  • go.mod: golang.org/x/net v0.58.0 → v0.60.0, still indirect. It carries x/sys v0.47.0 → v0.48.0 and x/text v0.41.0 → v0.42.0 with it; nothing pulls x/net back down.
  • sbom.json regenerated — the three version bumps above and nothing else.
  • Every go-version in ci.yml (matrix, supply-chain, lint, config-examples, build) and in release.yml is pinned to 1.26.10. The floating '1.26' in release.yml is how v3.8.2 ended up on 1.26.8; a release toolchain is now deterministic and auditable.

Verification

The artifact actually moved — go version -m on the linux/amd64 binary:

```
cbox-init: go1.26.10
dep golang.org/x/net v0.60.0
dep golang.org/x/sys v0.48.0
dep golang.org/x/text v0.42.0
```

Scanned the way the downstream gate scans, trivy rootfs --severity CRITICAL,HIGH --ignore-unfixed:

binary findings
this branch (go1.26.10 + x/net v0.60.0) 0
same source on go1.26.8 + x/net v0.58.0 4 (exactly the table above)

The before/after rules out a scan that simply does not know these CVEs.

Local make check equivalent, all green: fmt-check, vet, lint (0 issues), test (24 packages, race + coverage), cover-check (81.8% vs 78.0% floor), govulncheck (no vulnerabilities), sbom-check, license-check (68 deps, all permissive), check-configs (16/16), go test -race -short ./..., and go mod tidy is a no-op on the committed tree.

Follow-up, not in this PR

Dockerfile:2 is still FROM golang:1.27-alpine — floating, the same hole that caused this, and on a different Go line than go.mod. It resolves to a patched 1.27.3 today so it is not a finding, and it builds the ghcr image rather than the three release artifacts php-baseimages consumes. Worth pinning deliberately, but not inside a security patch release.

…9, -97031)

The 3.8.2 binaries were built by a floating `go-version: '1.26'`, which
resolved to 1.26.8 and shipped three HIGH denial-of-service advisories in the
standard library -- CVE-2026-78667 (net/http, crafted Range headers),
CVE-2026-78669 (net/http2, excessive HTTP/2 SETTINGS frames) and
CVE-2026-97031 (crypto/tls, multiple ECH outer extension references) -- plus
CVE-2026-78669 a second time in x/net v0.58.0's own HTTP/2. cbox-init serves
HTTP on the metrics, readiness and management ports, so none of these were
dead code, and the downstream image scan refused to promote any tag.

No behaviour change. The toolchain is pinned to 1.26.10 and x/net to v0.60.0
(which carries x/sys v0.48.0 and x/text v0.42.0 with it), and every
`go-version` in CI and in the release workflow is pinned to the same patch, so
a release is built by the toolchain that was scanned rather than whatever the
runner resolves that day.

Verified: `trivy rootfs --severity CRITICAL,HIGH --ignore-unfixed` on the
linux/amd64 binary reports 0 findings, against 4 on the same source built with
1.26.8 and x/net v0.58.0; `go version -m` on the binary records go1.26.10 and
golang.org/x/net v0.60.0.
`make sbom-check` failed in CI on a document that passed locally. sbomnorm
normalises the root component's version to 0.0.0 in the `version` field
unconditionally, but rewrote the version inside the root purl and bom-ref by
replacing the literal `name@oldVersion` -- and returned early when oldVersion
was empty. cyclonedx-gomod cannot resolve a version for the main module in
every checkout: inside a git worktree it warns "failed to determine version of
main module" and emits a version-less purl. Regenerating there therefore wrote
`pkg:golang/github.com/cboxdk/init?type=module` where a normal checkout writes
`...@0.0.0`, and the result passed `sbom-check` locally (both sides of its diff
were generated the same way) while failing it in CI.

The purl and bom-ref are now pinned to 0.0.0 whether or not a version was
resolved, matching the `version` field that was already being set. A shallow
clone and a git worktree now produce byte-identical SBOMs.

sbom.json is regenerated: the only change against 3.8.2's committed document
is the three dependency bumps from the previous commit, with the root module's
identity back to what it has always been.

Tests cover both paths, the already-normalised input, and that neither a
dependency nor a longer module path sharing the root's prefix is rewritten.
@sylvesterdamgaard
sylvesterdamgaard force-pushed the claude/interesting-easley-b46fb1 branch from e91c6bd to d342ebf Compare October 20, 2026 15:40
@sylvesterdamgaard

Copy link
Copy Markdown
Contributor Author

Pushed d342ebf, which fixes the Supply chain failure, and rewrote the branch to drop the stamp commit. Every other check was green on the first run, including Test on 1.26.10 on both runners — so actions/setup-go resolves the new pin fine.

The sbom-check failure was mine, and @0.0.0 is the correct form, not a new serialization to bake in. The committed sbom.json has carried pkg:golang/github.com/cboxdk/init@0.0.0?type=module since long before this PR; my regeneration stripped it.

tools/sbomnorm sets the root component's version field to 0.0.0 unconditionally, but rewrote the version inside the root purl and bom-ref by replacing the literal name@oldVersion — and returned early when oldVersion was empty. cyclonedx-gomod can't resolve a main-module version in every checkout: inside a git worktree it warns failed to determine version of main module: git: reference not found and emits a version-less purl. I regenerated in a worktree, so I wrote the bare purl — and sbom-check passed locally because both sides of its diff were generated the same wrong way. CI, on a real checkout, generated @0.0.0 and the diff fired.

So the generator version did not move; cyclonedx-gomod is pinned at v1.10.0 in the Makefile and the Go bump doesn't affect it.

The fix pins the purl and bom-ref to 0.0.0 whether or not a version resolved, matching the version field that was already being set. Verified by generating from a --depth 1 --no-tags clone (resolves a version, no warning) and from this worktree (does not resolve one) — byte-identical sbom.json. sbom.json here now differs from 3.8.2's only by the three dependency bumps, root identity untouched.

Worth knowing independently of this PR: make sbom run from a git worktree was silently producing a document that differed from CI's. That trap is now closed, with tests for both paths, idempotence, and non-rewriting of dependencies and of longer module paths sharing the root's prefix.

Also moved stamp 3.8.3 off this branch. Checking main's history, stamp commits are single-parent with no (#NNN) and land directly on main after the fix squash-merges (64e2547, 94e5aeb, 7591704, 68b625c, 9653d74). This PR now carries only the fix plus its ### Security entry under [Unreleased]; the stamp goes on main after merge, before the tag.

Full local gate green on the committed tree: fmt, vet, lint (0 issues), tests with race, coverage 82.0% vs the 78.0% floor, govulncheck clean, sbom-check, license-check, 16/16 configs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant