Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

Hosted Go redirect's not_in_module_graph gate counts a go.sum `/go.mod`-only line as "in the graph", so on a go 1.16 module it writes an inert replace for an unselected version and VEX attests not_affected

Ouverte
#509 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Personne n'a encore pris cette issue.

Évaluation

Difficulté
4/5
Temps estimé
3-5 jours
Accessibilité débutants
56/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
go, rust
Domaine
cli, devtools, security

Piste de recherche

Reproduce the fixture shape from crates/socket-patch-cli/tests/e2e_golang_hosted_build.rs, then read the gate at crates/socket-patch-core/src/patch/redirect/mod.rs:6228 and GoSum::has_module_version in crates/socket-patch-core/src/vendor/go_sum_edit.rs. Confirm how /go.mod-only entries pass the hosted check, and inspect crates/socket-patch-core/src/vex/discover/golang.rs for the related attestation path. Done means the go 1.16 scenario is refused without writes and VEX does not attest an unselected replacement.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

agent:triaged bug bughunt pm:go priority:p2

[agent] Found by the scheduled Go modules bug-hunt routine (ledger #317).

Summary

The hosted golang rewriter has a build-graph gate: a module that go.mod doesn't require and go.sum doesn't list at the patched version is refused with redirect_golang_not_in_module_graph. The go.sum half of the gate uses GoSum::has_module_version. That function accepts either the zip line (M v h1:) or the /go.mod line (M v/go.mod h1:).

Go writes a M v/go.mod line for every version that MVS reads while it builds the graph, not only the version it selects. A go ≤ 1.16 go.mod doesn't list transitive requirements. So when two dependencies require different versions of M, the losing version's /go.mod line passes the gate. get --mode hosted / scan --mode hosted then writes replace M v1.0.0 => patch.socket.dev/gopatch/<uuid> … for a version the build never links. It reports redirected: 1, and vex attests not_affected (redirected), while every build, including a fresh day-2 machine, links the unpatched selected version.

#392 cites this hosted gate as the correct behaviour that agent mode lacks. This issue is about the gate itself: it doesn't fire in the go 1.16 shape from #392.

Impact

A project on a pre-1.17 go.mod (still common in long-lived repos; module mode has been the default since 1.16) gets a committed hosted redirect and a not_affected OpenVEX statement for a CVE whose vulnerable code is compiled in. The refusal that exists to prevent exactly this ("Its replace would be inert, and confirming it would attest a patch no build links", redirect/mod.rs:6232) doesn't fire.

Repro (Linux, go 1.24.7, hermetic file GOPROXY + local mock patch API)

The fixture has the same shape as crates/socket-patch-cli/tests/e2e_golang_hosted_build.rs (golang_get_uuid_hosted_day2_machine_builds): the view/<uuid> and /patches/package mocks with a goproxy registryOverride, and patch.socket.dev/gopatch/<uuid> v1.0.0-socketpatch.1 served from the file proxy with harvested h1: sums. Upstream example.com/upstream has v1.0.0 and v1.0.1, both Greeting() = "PRISTINE". [email protected] requires upstream v1.0.0 and [email protected] requires upstream v1.0.1. Every module says go 1.16. The patch targets upstream v1.0.0.

export GOPROXY=file://$T/proxy GOMODCACHE=$T/modcache GOSUMDB=off GOFLAGS=-mod=mod GOTOOLCHAIN=local GOENV=off
# consumer/go.mod: module example.com/consumer / go 1.16 / require ( example.com/mida v1.0.0 ; example.com/midb v1.0.0 )
go mod tidy
grep upstream go.sum
#   example.com/upstream v1.0.0/go.mod h1:iZuR…     <- read by MVS, NOT selected (no zip line)
#   example.com/upstream v1.0.1 h1:wQ2T…
#   example.com/upstream v1.0.1/go.mod h1:iZuR…
go list -m example.com/upstream                   # example.com/upstream v1.0.1
socket-patch get $UUID --mode hosted --yes --json --api-url http://127.0.0.1:$PORT --org test-org --api-token fake
#   "status": "success", "redirect": {"redirected": 1, "rewrittenFiles": ["go.mod","go.sum"], "warnings": []}
grep replace go.mod
#   replace example.com/upstream v1.0.0 => patch.socket.dev/gopatch/5555…5555 v1.0.0-socketpatch.1
go run .                                          # OUT: PRISTINE PRISTINE
socket-patch vex --api-url … --product pkg:golang/example.com/consumer --output v.json
#   exit 0, "status": "not_affected"
# fresh day-2 machine (empty GOMODCACHE/GOCACHE, GOFLAGS=, GOSUMDB=bogus): go run .  -> OUT: PRISTINE PRISTINE

It reproduced twice in fresh fixtures on main 61cfb9b.

Controls:

  • The same graph with a go 1.21 go.mod: tidy adds require example.com/upstream v1.0.1 // indirect, and hosted correctly warns redirect_golang_version_mismatch and writes nothing. So only the "absent from require" branch is affected.
  • A plain project that requires upstream v1.0.0 directly: hosted redirects, and day-2 builds PATCHED (pass).

Expected vs actual

  • Expected: CLI_CONTRACT.md (scan --mode hosted): "A golang module that go.mod does not require and go.sum does not list at the patched version is outside the build graph and is refused with redirect_golang_not_in_module_graph (nothing written)." docs/ecosystems.md (Go): "A replacement targets an exact original module version. Updating the require can leave it unused". README vex: the attestation "only covers patches that are actually applied". A /go.mod-only go.sum line means the version's go.mod was read during MVS, not that its code is built. The gate should require the zip h1: line (or the selected build-list version) before treating M@v as in the graph.
  • Actual: the redirect is written, redirected: 1, no warning, and VEX gives not_affected. Every build links v1.0.1, unpatched.

OS × version

OS go toolchain consumer go directive hosted get build vex
Linux 1.24.7 1.16 redirected: 1, no warning PRISTINE (local and fresh day-2) not_affected
Linux 1.24.7 1.21 redirect_golang_version_mismatch, nothing written n/a n/a (pass)
macOS / Windows — — not run: probe branches are blocked from this sandbox. The logic is pure go.mod/go.sum text, so it doesn't depend on the OS.

First bad version: not a regression. The gate was added in #252 (872b591), after release 4.0.0, which had no gate at all.

Suspect code

  • crates/socket-patch-core/src/patch/redirect/mod.rs:6228 (else if !go_sum.has_module_version(&fname, &dep.version) && …): the build-graph gate.
  • crates/socket-patch-core/src/vendor/go_sum_edit.rs:368 GoSum::has_module_version (and the free fn at :104): it matches M v/go.mod as well as M v . For the graph gate, only the zip line shows that the version's packages are built.
  • The VEX side (crates/socket-patch-core/src/vex/discover/golang.rs, manifest-less hosted discovery) attests the replace without a selected-version check, so a gate fix should probably be mirrored there.

Related: #392 (agent mode has no gate at all), #391 (vex doesn't cross-check the replace version).

Langage dominant
Rust
Étoiles
8
Forks
0
Merge moyen
1 j 7 min
PR mergées (30 j)
178

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de SocketDev/socket-patch

Toutes les issues de SocketDev/socket-patch

Issues similaires

Plus d'issues Rust

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.