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
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 56/100
调研方向
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.
由索引模型根据 Issue 内容生成。
描述
[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.21go.mod: tidy addsrequire example.com/upstream v1.0.1 // indirect, and hosted correctly warnsredirect_golang_version_mismatchand writes nothing. So only the "absent fromrequire" 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 withredirect_golang_not_in_module_graph(nothing written)." docs/ecosystems.md (Go): "A replacement targets an exact original module version. Updating therequirecan leave it unused". READMEvex: 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 ziph1:line (or the selected build-list version) before treatingM@vas in the graph. - Actual: the redirect is written,
redirected: 1, no warning, and VEX givesnot_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:368GoSum::has_module_version(and the free fn at:104): it matchesM v/go.modas well asM 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).
- 主要语言
- Rust
- 星标
- 8
- 派生
- 0
- 平均合并
- 22 小时 30 分钟
- 30 天内合并 PR
- 329
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
SocketDev/socket-patch 的其他 Issue
-
`apply --check` drift report tells you to run `socket-patch apply` without the `-g` / `--global-prefix` / `--cwd` it was given, so following it patches nothing and exits 0可能已有人在做 关联的 PR 仍在进行中或已合并。 未关闭agent:triaged bug bughunt pm:pipenv priority:p1
难度 2/5 1-3 小时 新手友好度 72/100
SocketDev/socket-patch#1219 · 1 条评论 ·
维护者通常 1 天内回复
-
Human `scan --mode vendored --prune` silently skips the vendored GC when no remaining package has a patch, so an `npm uninstall`ed vendored entry is never reverted (exit 0), while `--json` reverts it and `vendor --check` keeps pointing at that same command可能已有人在做 关联的 PR 仍在进行中或已合并。 未关闭agent:triaged bug bughunt pm:npm priority:p2
难度 2/5 1-3 小时 新手友好度 85/100
SocketDev/socket-patch#1127 · 1 条评论 ·
维护者通常 1 天内回复
-
agent:triaged bug bughunt pm:bundler priority:p1
难度 2/5 1-3 小时 新手友好度 75/100
SocketDev/socket-patch#1125 · 1 条评论 ·
维护者通常 1 天内回复
-
agent:triaged bug bughunt pm:npm priority:p3
难度 2/5 1-3 小时 新手友好度 75/100
SocketDev/socket-patch#1072 · 1 条评论 ·
维护者通常 1 天内回复
-
scan exits 1 in human output but 0 with --json when every patch query returns nothing可能已有人在做 关联的 PR 仍在进行中或已合并。 未关闭agent:triaged arch-audit bug priority:p3
难度 2/5 1-3 小时 新手友好度 85/100
SocketDev/socket-patch#1062 · 1 条评论 ·
维护者通常 1 天内回复
查看 SocketDev/socket-patch 的全部 Issue
相似的 Issue
-
[Feature]: [P3] engine-rs: the package source hash should ignore line endings and untracked files未关闭
难度 2/5 1-3 小时 新手友好度 70/100
maniator/verticopolis#880 ·
维护者通常 1 天内回复
-
IO.get_env on Node truncates names at embedded NUL可能已有人在做 @Yi-111-a 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 82/100
HigherOrderCO/Bend#1449 · 1 条评论 ·
-
难度 2/5 1-3 小时 新手友好度 82/100
维护者通常 1 天内回复
-
documentation
难度 2/5 1-3 小时 新手友好度 66/100
维护者通常 3 天内回复
-
难度 2/5 1-3 小时 新手友好度 62/100
维护者通常 1 天内回复