GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — Fix npm 6 installing unpatched aliases (#432) by mikolalysenko · Pull Request #813 · SocketDev/socket-patch Conversation
|
| Lock | Alias mirror node resolved |
npm 6.14.18 ci |
npm 8.19.4 / 10.9.4 ci |
|---|---|---|---|
| v2 | registry (hosted before this fix) | unpatched, exit 0 | patched |
| v2 | hosted URL (hosted after this fix) | fails closed: EINTEGRITY (npm 6 refetches an alias from the registry) | patched |
| v2 | file:.socket/vendor/... (vendored after this fix) |
patched | patched |
| v1 | hosted URL (after this fix) | fails closed (existing v1 caveat) | patched |
Hosted mode can't make npm 6 install an aliased hosted tarball. So the
fix makes that case fail closed and warn loudly, and the warning points
npm 6 users at vendored mode.
New tests, each red with the fix disabled (identity decode, no mirror
check) and green with it:
| Test | Without fix | With fix |
|---|---|---|
patch::redirect::tests::npm_v2_legacy_alias_mirror_is_rewired_and_warned (hosted v2, plain and scoped alias) |
FAILED | ok |
patch::redirect::tests::npm_v1_alias_entry_is_rewired (hosted v1 alias) |
FAILED | ok |
vendor::npm_lock::tests::v2_legacy_alias_node_is_rewired_and_reverted (vendored rewire and byte-exact revert) |
FAILED | ok |
vex::discover::npm::tests::v2_alias_mirror_left_on_the_registry_contests_the_ref (hosted and vendored) |
FAILED | ok |
vex::discover::npm::tests::lockfile_v1_alias_node_is_its_target |
FAILED | ok |
vex::discover::npm::tests::stale_alias_mirror_contests_the_sibling_lock_ref (Bugbot: a stale shrinkwrap mirror also contests package-lock.json) |
FAILED | ok |
redirect_golden case npm/package-lock-v3/legacy-alias-mirror-v2 (byte-exact rewrite, edits, warnings) |
FAILED | ok |
upstream_restore_golden round trip of the same case (rewrite → discovery → rollback back to the original bytes) |
— | ok |
vex::discover::npm::tests::v2_alias_mirror_that_agrees_attests (guard: an agreeing mirror still attests) |
ok | ok |
e2e e2e_vendor_npm_build::npm6_installs_a_vendored_v2_alias_from_its_legacy_mirror (real npm 6 installs patched bytes; revert byte-exact) |
— | ok (npm 6.14.18, lock written by npm 10.9.4) |
The VEX discovery golden (vex-discover-golden/redirect-npm.json) only
gained the two new fixture entries. No existing entry changed.
Local checks:
cargo fmt --all -- --check: main itself is not fmt-clean with theredirect/mod.rs,cargo clippy --workspace --all-features -- -D warnings: cleancargo test --workspace --all-features: 9,730 passed, 253 ignored, 12 failed. All 12 are write-failure tests (*_write_failure_*, *unremovable*, read-only .socket/vendor) that need a non-root user to make chmod stick; this sandbox runs as root (uid 0). None touch npm lock code, and CI runs them as non-root.e2e_vendor_npm_build --include-ignored passes in full under npm 10.9.4 and under npm 6.14.18 (lock writer npm 10.9.4), 18/18 each. e2e_redirect_npm_build --include-ignored passes 13/15 under npm 10.9.4 and 14/15 under npm 6.14.18. The failures are the hosted rollback tests, whose live registry.npmjs.org fetch can't verify this sandbox's TLS-intercepting proxy: reqwest is built with bundled webpki roots and ignores SSL_CERT_FILE. That fetch is for a plain (non-alias) package, a path this PR doesn't change, and it runs normally on CI.npm_v2_legacy_alias_mirror_is_rewired_and_warned, golden legacy-alias-mirror-v2v2_legacy_alias_node_is_rewired_and_reverted, e2e npm6_installs_a_vendored_v2_alias_from_its_legacy_mirrorv2_alias_mirror_left_on_the_registry_contests_the_ref, stale_alias_mirror_contests_the_sibling_lock_refnpm_v1_alias_entry_is_rewired, lockfile_v1_alias_node_is_its_targetupstream_restore_golden round tripNone. The npm/pypi/gem wrappers only dispatch to the binary, so they
need no change.
🤖 Generated with Claude Code
Note
Medium Risk
Touches npm lockfile rewrite, VEX discovery, and vendoring paths that affect install integrity and attestation; behavior change for alias-heavy v2 locks but heavily tested with fail-closed warnings for npm 6 hosted aliases.
Overview
Fixes #432: npm alias installs in the legacy dependencies tree (v1 locks and the v2 mirror npm 6 reads) are now treated as their real name@version instead of matching only the alias key.
Lock handling: Shared npm_legacy_identity decodes "version": "npm:[email protected]". Hosted redirect and vendored rewire those mirror nodes (removes vendor_legacy_alias_skipped). Hosted adds redirect_npm_legacy_alias_client when a v2 alias mirror was rewritten—npm 6 still fetches aliases from the registry, so installs fail EINTEGRITY unless users vendor.
VEX: drop_mirror_unwired withholds attestation when packages is patched but the v2 legacy mirror still points at the registry (pre-fix locks), including contesting sibling npm locks.
Tests/docs: New unit/golden/e2e coverage (npm 6 vendored alias + revert), refactored Npm6Cell e2e helper, and small vex_consumed adjustments for resolver behavior after #605.
Reviewed by Cursor Bugbot for commit 6548559. Configure here.
Generated by Claude Code
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Assisted-by: Claude Code:claude-opus-5-5
A lockfileVersion 2 package-lock.json keeps a legacy `dependencies`
mirror for npm 6, which spells an alias install as
`"lp": {"version": "npm:[email protected]"}`. Hosted scans matched mirror
nodes on a plain version only, so the alias node silently stayed on
the registry, and a lockfileVersion 1 alias lock pinned nothing at all
("no package-lock.json entry"). Rollback could not restore such a node
either.
Every reader of the legacy tree now decodes the alias through one
helper. Hosted scans rewire the alias node with the rest, and rollback
restores it. npm 6 fetches an aliased dependency from the registry
whatever `resolved` says, so under npm 6 the pinned lock fails closed
(EINTEGRITY) instead of installing unpatched bytes, and the run warns
`redirect_npm_legacy_alias_client`.
Refs #432
Assisted-by: Claude Code:claude-opus-5-5
Vendoring skipped the v2 mirror node of an npm alias with `vendor_legacy_alias_skipped`, so npm 6 installed the unpatched registry tarball through it. npm 6 does install an alias node from a `file:` resolved (checked against npm 6.14.18), so the node is now rewired like every other mirror node and revert restores it. Refs #432 Assisted-by: Claude Code:claude-opus-5-5
Lockfile-only VEX read a v2 lock's `packages` half only, so it attested `not_affected` for a package whose legacy mirror (what npm 6 installs from) still resolved to the registry, as locks written before this fix do for npm aliases. Such a ref is now diagnosed as unattributable and not attested. A lockfileVersion 1 alias node is read as an install of its target package. Fixes #432 Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
When npm-shrinkwrap.json's legacy mirror still resolved a package from the registry, VEX dropped the shrinkwrap's own ref but still attested the same package from package-lock.json, although npm 6 installs from the shrinkwrap. A mirror node off Socket now counts as resolving the package elsewhere, so the sibling lock's ref is contested too. Refs #432 Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
[agent] Labeled Ready for review.
Slack announcement not sent this run (no Slack send tool available), so the next run will retry. Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Combined main's located npm walk (npm_lock_located_nodes, walk locate flag, unwired as purl→location map) with this PR's alias-aware legacy mirror nodes and drop_mirror_unwired; npm-compatibility table keeps main's takeover note and this PR's npm 6 alias row. Co-Authored-By: Claude <[email protected]>
|
bugbot run Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Main has been red since #605: two commands::vex_consumed tests assume the name-keyed resolver never returns npm-aliased copies, but #605 taught it to probe bundled store trees. Port #851's test-only fix so this PR's CI runs on a green base. It becomes a no-op once #851 lands. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01EgBZwmqgXLZaRGyfDFoWwp
|
[agent] Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
bugbot run Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 6548559. Configure here.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Burn-down agent: Ready for review at
Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
…check (#879) npm 7-12 `npm install` on a vendored lockfileVersion 2 package-lock.json or npm-shrinkwrap.json re-saves the legacy `dependencies` mirror node without `resolved` (npm never writes one for a `file:` resolution there), keeping only `version` and the patched `integrity`. Since #813, `drop_mirror_unwired` read a missing `resolved` as "resolves from a non-Socket source", so the wired `packages` ref was dropped: `vex` refused the patch (`patched_ref_unattributable`, `vendor_unwired`) and `vendor --check` failed with "wiring missing", although npm 7+ installs the patched bytes and npm 6 fails closed with EINTEGRITY on the patched pin. A mirror node with no `resolved` whose SRI integrity equals the pin of a `packages` ref for the same purl in that lock now agrees and contests nothing. A `resolved`-less node pinned to other bytes (the registry tarball) is still what npm 6 installs unpatched and keeps contesting the ref (#432). Both `vex` and `vendor --check` read this discovery, so both are fixed. Covered by core discovery tests (plain dep and alias, both lock flavors) and a CLI e2e test over vex + vendor --check. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
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
There was an error while loading. Please reload this page.