GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — 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) · Issue #405 · SocketDev/socket-patch

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

New issue
Copy link
New issue
Copy link
Closed
#496
Closed
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
#496
Copy link
Labels
agent:triagedbugSomething isn't workingSomething isn't workingbughuntFound by a scheduled package-manager bug-hunt agentFound by a scheduled package-manager bug-hunt agentpm:bunBunBunpriority:p1

Description

@mikolalysenko
Mikola Lysenko (mikolalysenko)
opened on Oct 1, 2026
Issue body actions

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

Activity

  1. Mikola Lysenko (mikolalysenko)
    added
    bugSomething isn't workingSomething isn't working
    bughuntFound by a scheduled package-manager bug-hunt agentFound by a scheduled package-manager bug-hunt agent
    pm:bunBunBun
    on Oct 1, 2026
  2. mikolalysenko commented on Oct 1, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 1, 2026
    CollaboratorAuthor
    More 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_copies then 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

  3. Mikola Lysenko (mikolalysenko)
    added
    agent:triaged
    priority:p1
    on Oct 1, 2026
  4. mikolalysenko commented on Oct 1, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 1, 2026
    CollaboratorAuthor
    More 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        # [email protected] vendored, bun.lock rewired
    # not reinstalled: node_modules/.bun/[email protected]/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 vex warnings
    linker = "isolated" .bun/[email protected]/… unpatched [] (missing)
    linker = "hoisted" (control) node_modules/is-number unpatched ["vendored_tree_out_of_sync"]

    After a fresh bun install --frozen-lockfile, the isolated store copy (.bun/[email protected]+vendor+npm+<uuid>+is-number-7.0.0.tgz/…) is patched and vex is correct. A fix for the .bun store lookup should restore the warning too.


    Generated by Claude Code

  5. mikolalysenko commented on Oct 1, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 1, 2026
    CollaboratorAuthor
    More actions

    [agent] Re-triaged after the vendored-mode comment: still priority:p1. The missing vendored_tree_out_of_sync warning 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

  6. mikolalysenko commented on Oct 1, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 1, 2026
    CollaboratorAuthor
    More 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, .deno and Yarn 4's .store are skipped). Branch: agent/fix-npm-crawler-isolated-stores. Claim-ID: 2026-10-01T19:20:55Z-253dcb


    Generated by Claude Code

  7. Mikola Lysenko (mikolalysenko)
    added
    agent:claimed
    on Oct 1, 2026
  8. mikolalysenko commented on Oct 1, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 1, 2026
    CollaboratorAuthor
    More actions

    [agent] Draft fix PR: #496


    Generated by Claude Code

  9. Mikola Lysenko (mikolalysenko)
    added a commit that references this issue on Oct 2, 2026

    Fix npm crawler missing Bun, Deno and Yarn 4 stores (#366, #373, #405, …

    35de754
  10. Mikola Lysenko (mikolalysenko)
    closed this as completedin #496on Oct 2, 2026
  11. Mikola Lysenko (mikolalysenko)
    removed
    agent:claimed
    on Oct 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:triagedbugSomething isn't workingSomething isn't workingbughuntFound by a scheduled package-manager bug-hunt agentFound by a scheduled package-manager bug-hunt agentpm:bunBunBunpriority:p1

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.