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

Agent-mode npm apply, apply --check and vex skip a declared workspace member whose directory is named build, dist, vendor, tmp, temp or coverage, so its nested copy stays unpatched while VEX attests not_affected

Ouverte
#1,627 3 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

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

@mikolalysenko y travaille déjà.

Depuis le 17/10/2026.

  • #1628 par @mikolalysenko — ouverte

Évaluation

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

Piste de recherche

Start with crates/socket-patch-core/src/crawlers/npm_crawler.rs, especially SKIP_DIRS and workspace_children near line 2965; compare with bun_workspace_pattern_members_sync near line 768 and read docs/ecosystems.md for the crawl contract. Reproduce with the packages/build workspace from the issue, then check apply, apply --check, and vex. Done means declared members in skipped-name directories are crawled and their installed copies are handled consistently by all three commands.

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

Description

agent:claimed agent:triaged bug bughunt pm:npm priority:p1

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

Summary

The npm crawler's workspace walk prunes every directory named dist, build, coverage, tmp, temp, __pycache__ or vendor (SKIP_DIRS). It does this even when the root package.json workspaces field declares that directory as a member, and npm installs it from the root lock. When npm can't hoist a member's dependency (a version conflict with the root), npm installs it into <member>/node_modules/. A member at packages/build, packages/dist, tools/build or vendor/lib is common in real monorepos, and its nested copy is then never crawled. As a result:

  • apply patches the other copies and prints 1 of 1 targeted patch applied, 0 … not found on disk. The member's copy stays unpatched with no warning.
  • apply --check reports Patches are in sync.
  • vex attests not_affected / inline_mitigations_already_exist for the product.
  • At runtime, Node resolves the member's own unpatched copy (require.resolve('ms') from the member → <member>/node_modules/ms/index.js).

Impact

The tool reports a false security attestation (VEX not_affected) and a passing CI audit (apply --check), while a vulnerable copy that npm installed from the project's own lock runs in production code. Nothing warns about it.

Repro (Linux, npm 10.9.4 / Node 22; same on npm 8.19.4 and npm 12.2.1 / Node 24)

mkdir ws && cd ws && mkdir -p packages/app packages/build
echo '{"name":"root","version":"1.0.0","private":true,"workspaces":["packages/*"],"dependencies":{"ms":"2.1.3"}}' > package.json
echo '{"name":"app","version":"1.0.0","dependencies":{"ms":"2.0.0"}}'   > packages/app/package.json
echo '{"name":"build","version":"1.0.0","dependencies":{"ms":"2.0.0"}}' > packages/build/package.json
npm install
# -> node_modules/[email protected], packages/app/node_modules/[email protected], packages/build/node_modules/[email protected]
# Stage a .socket/manifest.json + blobs for pkg:npm/[email protected] that appends a marker to index.js
# (a hand-staged agent manifest; any real [email protected] patch behaves the same)
socket-patch apply
#   Summary: 1 of 1 targeted patch applied, 0 already patched, 0 not found on disk
grep -c socket-patched packages/app/node_modules/ms/index.js    # 1  (patched)
grep -c socket-patched packages/build/node_modules/ms/index.js  # 0  (UNPATCHED)
socket-patch apply --check          # Patches are in sync (1 patch checked).  exit 0
socket-patch vex --product pkg:npm/[email protected] -O vex.json   # statement: not_affected
(cd packages/build && node -p "require.resolve('ms')")       # …/packages/build/node_modules/ms/index.js (unpatched)

If you rename packages/build to packages/lib, both copies are patched (control).

Expected vs actual

  • Expected: CLI_CONTRACT (apply --check) says "each installed copy hashes to the record's afterHash", and drift is exit 1. docs/ecosystems.md ("npm: which node_modules trees are crawled") says the scan collects "every node_modules found in the directories below it (workspace members, nested projects)". The name-based prune is meant for build-output / cache dirs ("well-known non-workspace dirs" in the code comment), not for a directory that workspaces declares and that npm installs into from the root lock. At a minimum, the crawler should never let vex attest not_affected while such a copy is unpatched.
  • Actual: declared members whose directory names are in SKIP_DIRS are skipped silently by apply, apply --check, agent scan and vex.

Matrix (agent mode, main 657fce2)

OS npm / Node member dir apply patches member copy apply --check vex
Linux 10.9.4 / 22.22.0 packages/build no in sync (wrong) not_affected (wrong)
Linux 10.9.4 / 22.22.0 packages/dist no in sync (wrong) not_affected (wrong)
Linux 10.9.4 / 22.22.0 vendor/lib no in sync (wrong) not_affected (wrong)
Linux 10.9.4 / 22.22.0 tools/build no in sync (wrong) not_affected (wrong)
Linux 8.19.4 / 22.22.0 packages/build no in sync (wrong) not_affected (wrong)
Linux 12.2.1 / 24.22.0 packages/build no in sync (wrong) not_affected (wrong)
Linux 10.9.4 packages/lib (control) yes in sync not_affected (correct)

Release v5.0.1 (npm @socketsecurity/socket-patch) behaves the same, so this is not a regression since the last release. Not tested this run: hosted and vendored modes, which rewire from the lock rather than the crawl; macOS / Windows (probe branches are currently blocked for this routine, but the walk is OS-independent).

Suspect code

  • crates/socket-patch-core/src/crawlers/npm_crawler.rs:21 (SKIP_DIRS)
  • crates/socket-patch-core/src/crawlers/npm_crawler.rs:2965 (workspace_children, which applies SKIP_DIRS without consulting the root package.json workspaces globs; the crate already expands those globs for Bun in bun_workspace_pattern_members_sync, around line 768)

The crawler is shared by the other JS package managers, so pnpm / yarn / Bun workspaces with a member at such a path probably behave the same. This report is scoped to npm.

Langage dominant
Rust
Étoiles
8
Forks
1
Merge moyen
16 h 22 min
PR mergées (30 j)
583

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.