Hacktoberfest 2026:維護者為十月標記出來的 issue,仍然開放、適合新手。 瀏覽 Hacktoberfest issue

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)

未關閉
#405 1 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

維護者通常 1 天內回覆

還沒有人認領這個 Issue。

評估

難度
4/5
預估耗時
3-5 天
新手友好度
70/100
Issue 類型
缺陷
描述清晰度
描述清楚
活躍度
活躍
技術堆疊
bun, rust
領域
cli, security, tooling

研究方向

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:triaged bug bughunt pm:bun priority:p1

[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:

  1. Stale tree: right after scan rewrote bun.lock and before the user re-installs. The installed copy still has the vulnerable bytes, and vex already attests.
  2. Tampered or wrong install: after a real fresh bun install --frozen-lockfile, the hosted copy lives at node_modules/.bun/is-number@http+++…/node_modules/is-number. Removing the patch from that file doesn't change the verdict: it's still verified. With the hoisted linker the same edit gives not_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 vex re-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, so vex takes the "nothing installed" branch and attests from the pin, with action: 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's installed map plus the alias walk and identity fallback. None of these walks node_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 empty HostedCopies.paths means "none installed", which the lockfile basis then excuses. The npm crawler's missing .bun store 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 範本
  • 閱讀貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

SocketDev/socket-patch 的其他 Issue

查看 SocketDev/socket-patch 的全部 Issue

相似的 Issue

更多 Rust Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。