Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue 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

Đang mở
#509 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
56/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
go, rust
Lĩnh vực
cli, devtools, security

Hướng nghiên cứu

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.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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).

Ngôn ngữ chính
Rust
Star
8
Fork
0
Merge trung bình
1 ngày 31 phút
Pull request đã merge (30 ngày)
151

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của SocketDev/socket-patch

Tất cả issue của SocketDev/socket-patch

Issue tương tự

Thêm issue về Rust

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.