Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

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)

Ouverte
#405 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Personne n'a encore pris cette issue.

Évaluation

Difficulté
4/5
Temps estimé
3-5 jours
Accessibilité débutants
70/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
bun, rust
Domaine
cli, security, tooling

Piste de recherche

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.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

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

Langage dominant
Rust
Étoiles
8
Forks
0
Merge moyen
18 h 4 min
PR mergées (30 j)
70

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de SocketDev/socket-patch

Toutes les issues de SocketDev/socket-patch

Issues similaires

Plus d'issues Rust

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.