Hacktoberfest 2026:維護者為十月標記出來的 issue,仍然開放、適合新手。 瀏覽 Hacktoberfest issue

npm v2 lock: aliased packages stay on the registry in the legacy dependencies mirror (hosted silently, vendored with a warning), so npm 6 installs unpatched bytes while VEX attests not_affected

已關閉
#432 1 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

維護者通常 1 天內回覆

@mikolalysenko 已經在處理了。

開始於 2026年10月5日。

  • #813 來自 @mikolalysenko —— 未關閉

評估

難度
4/5
預估耗時
3-5 天
新手友好度
48/100
Issue 類型
缺陷
描述清晰度
描述清楚
活躍度
活躍
技術堆疊
node.js, rust
領域
cli, security

研究方向

Read crates/socket-patch-core/src/vendor/npm_lock.rs:950-972, the npm redirect code under crates/socket-patch-core/src/patch/redirect/, and manifest-less discovery under crates/socket-patch-core/src/vex/discover/. Run the supplied npm 6/npm 12 alias reproduction in hosted and vendored modes first. Done means the legacy alias behavior is safe or clearly reported in both modes, and lockfile-only VEX does not make a false not_affected attestation.

由索引模型根據 Issue 內容生成。

描述

agent:triaged bug bughunt pm:npm priority:p1

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

Summary

Take a lockfileVersion 2 package-lock.json, the format npm 7 and 8 write, which also carries the legacy dependencies mirror that npm 6 reads. When it holds an npm alias ("lp": "npm:[email protected]"), hosted and vendored mode rewrite only the packages["node_modules/lp"] entry. The mirror node dependencies.lp ("version": "npm:[email protected]") keeps its registry resolved and integrity.

  • Hosted (the v5 default) does this silently. Its only warning is redirect_npm_allow_remote.
  • Vendored warns vendor_legacy_alias_skipped ("npm 6 clients reading the v2 legacy mirror still install the UNPATCHED registry bytes through it"). See crates/socket-patch-core/src/vendor/npm_lock.rs:950-972.

In both modes, manifest-less socket-patch vex then attests the package not_affected from the lockfile. Meanwhile npm ci with npm 6 on that same committed lock installs the unpatched registry tarball and exits 0.

Non-aliased entries don't have this problem: the mirror is rewritten, and npm 6 installs the patched bytes. That holds for both hosted and vendored, and for nested entries too.

A related symptom in the same area: with an npm 6 lockfileVersion 1 lock and the same alias, hosted scan writes nothing. It warns redirect_npm_entry_not_found: no package-lock.json entry for [email protected] and exits 0 success, even though the lock contains the alias entry "lp": {"version": "npm:[email protected]", ...}.

Impact

Docs list npm 6 as able to install a v2 lock (docs/testing/npm-compatibility.md, docs/ecosystems.md:56). A project that commits a v2 lock and has any npm 6 consumer (CI image, developer machine) gets the vulnerable code. Its VEX document still claims the vulnerability is not exploitable, which is the false attestation VEX must never make. Vendored at least warns at write time. Hosted gives no signal at all.

Repro

This uses a local mock of the patch API (batch / by-package / patches/package / patches/view / the tarball route), with --patch-server-url pointing at it. The patched tarball prepends /* SOCKET-PATCHED */ to index.js.

SPA="--api-url http://127.0.0.1:8765 --org o --api-token fake --patch-server-url http://127.0.0.1:8765"
mkdir repro && cd repro
echo '{"name":"t","version":"1.0.0","private":true,"dependencies":{"lp":"npm:[email protected]"}}' > package.json
npx -y [email protected] install            # lockfileVersion 2

socket-patch scan $SPA --json        # hosted: status success, redirected 1, warnings: [redirect_npm_allow_remote]
node -e 'const l=require("./package-lock.json");console.log(l.packages["node_modules/lp"].resolved, l.dependencies.lp.resolved)'
#   http://127.0.0.1:8765/patch/npm/<token>/<uuid>/left-pad-1.3.0.tgz   https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz

# fresh checkouts of the committed files (package.json, package-lock.json, .npmrc)
(cp -r ../repro ../c6  && cd ../c6  && rm -rf node_modules && npx -y [email protected] ci && head -c 21 node_modules/lp/index.js)   # "/* This program is fr" (UNPATCHED)
(cp -r ../repro ../c12 && cd ../c12 && rm -rf node_modules && npx -y [email protected] ci && head -c 21 node_modules/lp/index.js)   # "/* SOCKET-PATCHED */"
(cp -r ../repro ../lo  && cd ../lo  && rm -rf node_modules && socket-patch vex $SPA -O v.json)                                 # 1 statement: not_affected

To see the vendored twin, run socket-patch scan --mode vendored $SPA instead of the hosted scan. It prints the vendor_legacy_alias_skipped warning. npm 6 ci again installs unpatched bytes, and lockfile-only vex is again not_affected.

Expected vs actual

  • Expected: CLI_CONTRACT.md's lockfile table says for npm lock v2: "v2 legacy dependencies mirror … legacy mirror rewritten". So the alias mirror node should be rewritten like the non-alias ones. Failing that, the run should at least fail loudly in hosted mode (the vendored warning parity). VEX should also withhold the attestation while a lock that some supported npm reads still resolves the package from the registry. That's the same principle as patched_ref_unattributable for the dual-lock shrinkwrap/package-lock case.
  • Actual: hosted rewrites only the packages half, silently. Vendored does the same with a warning. VEX attests not_affected in both modes, while npm 6 installs the unpatched bytes.

Matrix (Linux, Node 22.22)

Lock writer Mode npm 6.14.18 ci npm 12.1.0 ci lockfile-only vex
npm 8.19.4 (v2), alias lp + scoped alias @x/lp hosted unpatched patched not_affected
npm 8.19.4 (v2), alias vendored unpatched (warned at write) n/a not_affected
npm 8.19.4 (v2), plain is-number + nested copy (control) hosted patched patched not_affected (correct)
npm 6.14.18 (v1), alias hosted nothing written, redirect_npm_entry_not_found, exit 0 — no refs

First bad version

This isn't a v5 regression. Release 4.0.0 (scan --mode hosted) leaves the same alias mirror nodes on the registry. Main 2463257 behaves the same way.

Suspect code

  • Vendored: crates/socket-patch-core/src/vendor/npm_lock.rs:950 (rewrite_legacy_tree, the vendor_legacy_alias_skipped branch).
  • Hosted: the npm package-lock.json redirect under crates/socket-patch-core/src/patch/redirect/ has no counterpart warning and no alias-mirror rewrite.
  • VEX: manifest-less npm lock discovery (crates/socket-patch-core/src/vex/discover/) attests from the packages half without checking the legacy mirror.
主要語言
Rust
星號
8
分支
0
平均合併
1 天 7 分鐘
30 天內合併 PR
178

環境準備

  • 沒有 Dockerfile 或 Docker Compose 檔案
  • 沒有 Pull Request 範本
  • 閱讀貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

SocketDev/socket-patch 的其他 Issue

查看 SocketDev/socket-patch 的全部 Issue

相似的 Issue

更多 Rust Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。