With Bun's isolated linker, `vex` attests a hosted patch as not_affected (verified) while the installed copy under node_modules/.bun is still unpatched (v5 regression)
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 70/100
调研方向
Start with hosted_consumed_copies in crates/socket-patch-cli/src/commands/vex_consumed.rs and the npm crawler at crates/socket-patch-core/src/crawlers/npm_crawler.rs; then inspect the empty HostedCopies handling in crates/socket-patch-core/src/vex/verify.rs. Run the isolated-linker reproduction and hoisted control from the issue. Done means installed copies under node_modules/.bun are considered by VEX, so stale or tampered copies are not falsely reported as verified.
由索引模型根据 Issue 内容生成。
描述
[agent] Found by the scheduled Bun bug-hunt routine (ledger #306).
Summary
With Bun's isolated linker, socket-patch vex attests a hosted-mode patch as not_affected and reports it verified, even though the copy Bun actually installed (under node_modules/.bun/<name>@<version>/node_modules/<name>) does not carry the patch. The isolated linker is opt-in on Bun 1.2.x (linker = "isolated") and the default for fresh workspaces on Bun 1.3.x and 1.4.x.
v5 hosted mode is the default for scan. In that mode, vex treats a purl with no consumed copy as "nothing installed" and attests it from the lockfile pin. The npm copy lookup doesn't look inside Bun's .bun/ store, so a transitive package there is never found. That makes the pin the only evidence even when a stale (pre-reinstall) or tampered copy is installed. A hoisted install of the same project is handled correctly: not_applied, omitted from the document.
This is a regression from 4.0.0. 4.0.0 omits the same purl from the document (package_not_found).
Related: #366 shares the root cause (agent mode can't see packages under node_modules/.bun). That issue is about agent-mode scan/apply. This one is about hosted-mode VEX making a false attestation. #373 is the Deno counterpart of #366.
Impact
The document says not_affected / "Patched via Socket patch (redirected)" for a dependency the running code loads unpatched. That happens in two cases, both with exit 0 and status: success:
- Stale tree: right after
scanrewrotebun.lockand before the user re-installs. The installed copy still has the vulnerable bytes, andvexalready attests. - Tampered or wrong install: after a real fresh
bun install --frozen-lockfile, the hosted copy lives atnode_modules/.bun/is-number@http+++…/node_modules/is-number. Removing the patch from that file doesn't change the verdict: it's stillverified. With the hoisted linker the same edit givesnot_applied.
Every Bun ≥ 1.3 workspace that runs socket-patch scan && socket-patch vex hits case 1, because fresh workspaces default to the isolated linker.
Repro (Linux, Bun 1.4.2, main 2463257)
The patch API is a local mock that serves the batch, patches/package, patches/view and hosted tarball routes. SOCKET_PATCH_SERVER_URL points at it, so its tarball URL counts as a hosted pin. The patch prepends /* SOCKET-PATCHED … */ to [email protected]/index.js.
mkdir app && cd app
echo '{"name":"app","version":"1.0.0","dependencies":{"to-regex-range":"5.0.1"}}' > package.json
printf '[install]\nlinker = "isolated"\n' > bunfig.toml # omit on a Bun >=1.3 workspace: it's the default there
bun install
# node_modules/.bun/[email protected]/node_modules/is-number <- transitive, only in the store
socket-patch scan --mode hosted --json --yes --api-url $MOCK --org org --api-token fake
# status success, redirect.redirected 1 (bun.lock now pins the hosted URL)
grep -c SOCKET-PATCHED node_modules/.bun/[email protected]/node_modules/is-number/index.js # 0 (not reinstalled yet)
socket-patch vex --json --output out.vex.json --api-url $MOCK --org org --api-token fake
# status "success", events: [{"action":"verified","purl":"pkg:npm/[email protected]", ... "status":"not_affected"}]
# out.vex.json: not_affected, "Patched via Socket patch 2222…(redirected)"
Control in the same state: linker = "hoisted" gives is-number at node_modules/is-number and vex → skipped not_applied, no_applicable_patches, no document.
Workspace variant, with no bunfig on Bun 1.3.14 or 1.4.2: the root has workspaces: ["packages/*"], and packages/a depends on [email protected] and [email protected]. After a hosted scan and before a reinstall, vex reports left-pad as not_applied, because the direct dep is reached through its node_modules/left-pad symlink. It reports is-number as verified / not_affected, although neither store copy is patched.
Tamper variant (measured on Linux, Bun 1.4.2): run a fresh checkout and bun install --frozen-lockfile, so the hosted copy is installed and patched. Then delete the marker line from node_modules/.bun/is-number@http+++…/node_modules/is-number/index.js. vex still reports verified. The hoisted control reports not_applied.
Expected vs actual
- Expected (CLI_CONTRACT.md, "Patched via Socket patch (redirected)" row and "Manifest-less VEX"): "a post-install
socket-patch vexre-proves the lockfile wiring and hash-verifies the installed copy the build consumes". Only "with nothing installed" may it attest a discovered reference from its pin.HostedCopies(crates/socket-patch-core/src/vex/verify.rs:83-105) says a shared-location ecosystem's pristine copy "IS what runs" and must fail verification. - Actual: the consumed copy under
node_modules/.bun/is invisible to the lookup, sovextakes the "nothing installed" branch and attests from the pin, withaction: verified.
OS × version (hosted scan → vex before reinstall)
| OS | Bun 1.2.23 (linker = "isolated") |
Bun 1.3.14 (isolated / default workspace) | Bun 1.4.2 (isolated / default workspace) | hoisted control |
|---|---|---|---|---|
| Linux | fail | fail / fail | fail / fail | pass (not_applied) |
| macOS (macos-latest) | fail | fail / fail | fail / fail | pass |
| Windows (windows-latest) | fail | fail / fail | fail / fail | pass |
On Bun 1.2.23 a default workspace still installs hoisted, so that cell is correctly not_applied on all 3 OSes. That's expected, not a fix.
Regression check (Linux, Bun 1.4.2, isolated): release 4.0.0 → omitted (package_not_found), pass. main 2463257 (#277, v5) → attested, fail. So the first bad commit is the v5 consolidation (#277), the one that added manifest-less VEX's "attest from the pin when nothing is installed".
Suspect code
crates/socket-patch-cli/src/commands/vex_consumed.rs:69-121(hosted_consumed_copies): npm's shared-location copies come from the crawler'sinstalledmap plus the alias walk and identity fallback. None of these walksnode_modules/.bun/*/node_modules/<name>.with_store_variants(:323) only expands copies that were already found.crates/socket-patch-core/src/vex/verify.rs:98-105: an emptyHostedCopies.pathsmeans "none installed", which the lockfile basis then excuses. The npm crawler's missing.bunstore discovery (the same gap as #366,crates/socket-patch-core/src/crawlers/npm_crawler.rs) turns that into a false attestation.
A fix for #366 that teaches the crawler the .bun store would probably fix this too. Even so, vex should probably refuse to take the "nothing installed" branch while node_modules/.bun/ exists.
Probe run (3 OS × Bun 1.2.23 / 1.3.14 / 1.4.2, main built on each runner; cases iso-bunfig, ws-default, hoisted-control): https://github.com/SocketDev/socket-patch/actions/runs/36801259018
- 主要语言
- Rust
- 星标
- 8
- 派生
- 0
- 平均合并
- 18 小时 4 分钟
- 30 天内合并 PR
- 70
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
SocketDev/socket-patch 的其他 Issue
-
agent:triaged bug bughunt pm:composer priority:p2
难度 2/5 1-3 小时 新手友好度 90/100
SocketDev/socket-patch#515 · 1 条评论 ·
维护者通常 1 天内回复
-
agent:triaged bug bughunt pm:npm priority:p1
难度 2/5 1-3 小时 新手友好度 82/100
SocketDev/socket-patch#464 · 1 条评论 ·
维护者通常 1 天内回复
-
agent:triaged bug bughunt pm:npm priority:p1
难度 2/5 1-3 小时 新手友好度 82/100
SocketDev/socket-patch#433 · 1 条评论 ·
维护者通常 1 天内回复
-
agent:triaged bug bughunt pm:uv priority:p1
难度 2/5 1-3 小时 新手友好度 78/100
SocketDev/socket-patch#408 · 1 条评论 ·
维护者通常 1 天内回复
-
agent:triaged bug bughunt pm:yarn-berry priority:p1
难度 2/5 1-3 小时 新手友好度 82/100
SocketDev/socket-patch#370 · 2 条评论 ·
维护者通常 1 天内回复
查看 SocketDev/socket-patch 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
难度 1/5 1 小时以内 新手友好度 78/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 86/100
dani-garcia/vaultwarden#7801 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 90/100
boxlite-ai/boxlite#1814 ·
维护者通常 1 天内回复