Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Hosted npm pin in package-lock.json is attested by VEX in a Deno project, but deno.lock keeps installing the unpatched registry copy

Aperta
#406 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
65/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
javascript, rust
Ambito
cli, security

Direzione di ricerca

Start with crates/socket-patch-core/src/vex/discover/mod.rs:574, then compare the extractor logic in crates/socket-patch-core/src/vex/discover/npm.rs:87 and the hosted rewriter in crates/socket-patch-core/src/patch/redirect/mod.rs. Trace how deno.lock should participate in contested-lock detection and warnings; done means Deno registry resolutions prevent false VEX success and report the expected diagnostic or warning.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

agent:triaged bug bughunt pm:deno priority:p1

[agent] Found by the scheduled Deno bug-hunt routine (ledger #308).

Summary

In a Deno 2 project that uses package.json and also keeps an npm package-lock.json, scan --mode hosted rewrites only package-lock.json. It reports redirected: 1, status: success, exit 0, with no warning about deno.lock. Deno never reads package-lock.json, though: deno install (frozen or not) keeps installing the unpatched registry tarball pinned in deno.lock.

vex still attests the patch:

  • In-run scan --mode hosted --vex attests not_affected, even when Deno's unpatched node_modules copy is already on disk.
  • Standalone vex on a fresh checkout (lockfiles only, the CI shape) attests not_affected from the package-lock.json pin.

Only after a deno install does standalone vex see the installed copy and omit the patch (not_applied).

deno.lock resolves the same name@version from the registry, so this is the "contested lock" case that CLI_CONTRACT.md already handles for npm / pnpm / yarn / bun / vlt. deno.lock just isn't one of the locks it reads.

Impact

  • False VEX. A scanner fed the document suppresses the CVE, while the code Deno actually runs is unpatched.
  • False success. The hosted run's summary ("Switched 1 package to hosted patches") and its exit code tell a Deno user the dependency is patched. docs/ecosystems.md lists Deno hosted mode as "❌ not supported". Nothing in the output says the pin only takes effect for npm ci.
  • Dual Node/Deno repos (a committed package-lock.json plus deno.lock) are common for libraries and apps migrating to Deno 2.

Repro (Linux; Deno 2.9.6 / 2.2.15; npm 10; no API key)

A local stub of the public patch proxy grants one hosted patch for [email protected]. The stub serves a patched tarball whose index.js prepends globalThis.__SP=["is-odd-hosted"], plus a patch view with real before/after hashes. It's about 30 lines of http.server, with these routes: POST /patch/batch, GET /patch/by-package/<purl>, GET /patch/view/<uuid>, POST /patch/package returning {status:"granted", url:"$S/patch/npm/<uuid>/is-odd-3.0.1.tgz", artifacts:[{kind:"tarball", integrity:{sha512,…}}]}, and the tarball itself.

SP=/path/to/socket-patch            # main 2463257
export SOCKET_PROXY_URL=http://127.0.0.1:8770 SOCKET_PATCH_SERVER_URL=http://127.0.0.1:8770
mkdir mixed && cd mixed && export DENO_DIR=$PWD/../dd
echo '{"name":"m","version":"1.0.0","dependencies":{"is-odd":"3.0.1"}}' > package.json
echo '{"nodeModulesDir":"manual"}' > deno.json
echo 'import isOdd from "is-odd"; isOdd(3); console.log("loaded-patched="+JSON.stringify((globalThis as any).__SP||[]));' > probe.ts
npm install --package-lock-only --ignore-scripts      # package-lock.json
deno install                                          # deno.lock (v5) + node_modules
git init -q && git add -A && git commit -qm init

$SP scan --mode hosted --json --vex in.vex.json
#   status success, redirect.redirected 1, rewrittenFiles [.npmrc, package-lock.json],
#   warnings [redirect_npm_allow_remote] only. deno.lock is untouched.
#   in.vex.json: not_affected for pkg:npm/[email protected]

rm -rf node_modules                                   # = fresh clone
$SP vex --json -O v.json --product pkg:generic/t     # verified / not_affected

deno install --frozen                                 # succeeds; deno.lock unchanged
deno run -A probe.ts                                  # loaded-patched=[]   <- unpatched code runs
$SP vex --json -O v.json --product pkg:generic/t     # now: skipped not_applied (correct)

rm -rf node_modules && npm ci --ignore-scripts && node -e 'require("is-odd")(3);console.log(globalThis.__SP)'
#                                                     # [ 'is-odd-hosted' ]  <- only npm consumes the pin

Expected vs actual

  • Expected:
    • CLI_CONTRACT.md, Contested locks: "When one lock wires a package to a patch and another lock resolves the same name@version from a non-Socket source, the build's bytes depend on which package manager runs. The reference is then dropped with a patched_ref_unattributable diagnostic naming both files." deno.lock's npm section ("[email protected]": {"integrity": "sha512-…"}) is exactly such a registry resolution, so lockfile-only and in-run VEX should drop the ref with patched_ref_unattributable.
    • The hosted run should warn that deno.lock will keep installing the registry copy, the way vlt projects get redirect_vlt_sibling_lockfiles and lock-less ones get redirect_npm_no_lockfile. Per docs/ecosystems.md, Deno has no hosted mode.
  • Actual: the redirect is counted, no warning is given, and VEX attests not_affected while Deno runs the unpatched bytes.

Matrix (Linux sandbox, real Deno + real npm, runtime-checked)

Deno hosted scan result in-run --vex vex fresh clone deno install --frozen → code loaded vex after deno install
2.2.15 success, redirected 1, no deno warning not_affected (wrong) not_affected (wrong) unpatched not_applied (ok)
2.9.6 (reproduced 3×) same not_affected (wrong) not_affected (wrong) unpatched not_applied (ok)

Deno 1.46.3 wasn't tested. macOS and Windows weren't probed; nothing here is OS-specific (lockfile discovery only). Releases 3.3.0 and 4.0.0 weren't bisected, since manifest-less hosted VEX is new in v5 (#251).

Suspect code

  • crates/socket-patch-core/src/vex/discover/mod.rs:574 (contest_across_locks): elsewhere is fed by the npm / pnpm / yarn / bun / vlt / Python extractors, and there is no deno.lock reader, so a Deno registry resolution never contests a package-lock.json hosted ref.
  • crates/socket-patch-core/src/vex/discover/npm.rs:87 (push_uncontested): the same pairwise rule within the npm family.
  • The npm hosted rewriter in crates/socket-patch-core/src/patch/redirect/mod.rs has no deno.lock sibling check or warning.

Related: #405 (the same class of problem, where vex attests while the installed copy the runtime uses is unpatched, for Bun's isolated linker).

Lingua principale
Rust
Stelle
8
Fork
0
Merge medio
18h 4m
PR unite (30g)
70

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di SocketDev/socket-patch

Tutte le issue di SocketDev/socket-patch

Issue simili

Altre issue su Rust

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.