Repository navigation
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
Description
Activity
- addedbugSomething isn't workingSomething isn't workingbughuntFound by a scheduled package-manager bug-hunt agentFound by a scheduled package-manager bug-hunt agentpm:bunBunBun
on Oct 1, 2026 mikolalysenko commented
on Oct 1, 2026 CollaboratorAuthorMore actions[agent] Triaged:
priority:p1(Bun, npm family). Not a duplicate. #366 is the agent-mode symptom, and this is the hosted-VEX symptom.Shares root cause with #359, #362, #366, #373: the npm crawler recognizes dependency stores only by hard-coded directory names, so
node_modules/.bun/<name>@<ver>/node_modules/<name>is dropped by the generic hidden-entry skip.hosted_consumed_copiesthen sees no installed copy and VEX takes the "nothing installed" branch. Will be fixed together in #365, which I'm taking over this run.
Generated by Claude Code
mikolalysenko commented
on Oct 1, 2026 CollaboratorAuthorMore actions[agent] Bun bug-hunt routine (ledger #306): still reproduces on main
d984832. Here's a vendored-mode variant with the same root cause (the.bun/store is invisible to the installed-copy lookup).In vendored mode the attestation standing on the committed artifact is by design (CLI_CONTRACT "Vendored" row). But the contract also says "A present installed tree with different bytes only warns
vendored_tree_out_of_sync", and with the isolated linker that warning never fires:echo '{"name":"p","version":"1.0.0","dependencies":{"to-regex-range":"5.0.1"}}' > package.json printf '[install]\nlinker = "isolated"\n' > bunfig.toml && bun install socket-patch scan --mode vendored --json --yes $G # is-number@7.0.0 vendored, bun.lock rewired # not reinstalled: node_modules/.bun/is-number@7.0.0/node_modules/is-number/index.js is unpatched socket-patch vex --json -O o.json $G # success, verified, warnings: []
Bun 1.4.2, Linux, 2 runs each installed copy vexwarningslinker = "isolated".bun/is-number@7.0.0/…unpatched[](missing)linker = "hoisted"(control)node_modules/is-numberunpatched["vendored_tree_out_of_sync"]After a fresh
bun install --frozen-lockfile, the isolated store copy (.bun/is-number@.socket+vendor+npm+<uuid>+is-number-7.0.0.tgz/…) is patched andvexis correct. A fix for the.bunstore lookup should restore the warning too.
Generated by Claude Code
mikolalysenko commented
on Oct 1, 2026 CollaboratorAuthorMore actions[agent] Re-triaged after the vendored-mode comment: still
priority:p1. The missingvendored_tree_out_of_syncwarning has the same root cause (the.bun/store is invisible to the installed-copy lookup), so it's in scope here.
Generated by Claude Code
mikolalysenko commented
on Oct 1, 2026 CollaboratorAuthorMore actions[agent] Claiming this issue (with #366, #373, #495; shared root cause: the npm crawler only recognizes isolated stores by hard-coded names/shapes, so
.bun,.denoand Yarn 4's.storeare skipped). Branch: agent/fix-npm-crawler-isolated-stores. Claim-ID: 2026-10-01T19:20:55Z-253dcb
Generated by Claude Code
mikolalysenko commented
on Oct 1, 2026 CollaboratorAuthorMore actions
[agent] Found by the scheduled Bun bug-hunt routine (ledger #306).
Summary
With Bun's isolated linker,
socket-patch vexattests a hosted-mode patch asnot_affectedand reports itverified, even though the copy Bun actually installed (undernode_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,vextreats 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-modescan/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 andstatus: success:scanrewrotebun.lockand before the user re-installs. The installed copy still has the vulnerable bytes, andvexalready attests.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 vexhits 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/viewand hosted tarball routes.SOCKET_PATCH_SERVER_URLpoints at it, so its tarball URL counts as a hosted pin. The patch prepends/* SOCKET-PATCHED … */tois-number@7.0.0/index.js.Control in the same state:
linker = "hoisted"givesis-numberatnode_modules/is-numberandvex→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/*"], andpackages/adepends onto-regex-range@5.0.1andleft-pad@1.3.0. After a hosted scan and before a reinstall,vexreportsleft-padasnot_applied, because the direct dep is reached through itsnode_modules/left-padsymlink. It reportsis-numberasverified/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 fromnode_modules/.bun/is-number@http+++…/node_modules/is-number/index.js.vexstill reportsverified. The hoisted control reportsnot_applied.Expected vs actual
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.node_modules/.bun/is invisible to the lookup, sovextakes the "nothing installed" branch and attests from the pin, withaction: verified.OS × version (hosted
scan→vexbefore reinstall)linker = "isolated")not_applied)On Bun 1.2.23 a default workspace still installs hoisted, so that cell is correctly
not_appliedon 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. main2463257(#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 Bun isolated linker: transitive packages under node_modules/.bun are "not installed" in agent mode, and scan --mode agent exits 0 with them unpatched #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
.bunstore would probably fix this too. Even so,vexshould probably refuse to take the "nothing installed" branch whilenode_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