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
Maintainer thường phản hồi trong vòng 1 ngày
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 48/100
Hướng nghiên cứu
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.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
[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:
applypatches the other copies and prints1 of 1 targeted patch applied, 0 … not found on disk. The member's copy stays unpatched with no warning.apply --checkreportsPatches are in sync.vexattestsnot_affected/inline_mitigations_already_existfor 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'safterHash", and drift is exit 1. docs/ecosystems.md ("npm: whichnode_modulestrees are crawled") says the scan collects "everynode_modulesfound 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 thatworkspacesdeclares and that npm installs into from the root lock. At a minimum, the crawler should never letvexattestnot_affectedwhile such a copy is unpatched. - Actual: declared members whose directory names are in
SKIP_DIRSare skipped silently byapply,apply --check, agentscanandvex.
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 appliesSKIP_DIRSwithout consulting the rootpackage.jsonworkspacesglobs; the crate already expands those globs for Bun inbun_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.
- Ngôn ngữ chính
- Rust
- Star
- 8
- Fork
- 1
- Merge trung bình
- 16 giờ 39 phút
- Pull request đã merge (30 ngày)
- 584
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của SocketDev/socket-patch
-
agent:triaged bug bughunt pm:pipenv priority:p1
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
SocketDev/socket-patch#1608 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
agent:triaged bug bughunt pm:vlt priority:p1
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
SocketDev/socket-patch#1601 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
agent:triaged bug bughunt pm:npm priority:p3 ux
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
SocketDev/socket-patch#1072 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
agent:triaged bug bughunt pm:yarn-berry priority:p1
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 73/100
SocketDev/socket-patch#783 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Vendored scan exits 0 when .gitignore covers `.socket/vendor/state.json`, so the commit silently drops the ledger and every other checkout's `rollback` fails with vendor_ledger_missingCó thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mởbug bughunt pm:pnpm
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 76/100
SocketDev/socket-patch#1638 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của SocketDev/socket-patch
Issue tương tự
-
enhancement
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
metasequoiaime/msime#9113 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
area:desktop priority:p2 type:chore
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
Maintainer thường phản hồi trong vòng 1 ngày
-
area: supply-chain
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 73/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 67/100
-
Refresh stale docsĐang mở
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 67/100
OpenCarControls/firmware#35 ·