Skip to content

fix(parsers): preserve npm shrinkwrap precedence - #1485

Merged
sonukapoor merged 1 commit into
OWASP:mainfrom
vianmangal:codex/issue-1484-shrinkwrap-precedence
Nov 3, 2026
Merged

sonukapoor merged 1 commit into
OWASP:mainfrom
vianmangal:codex/issue-1484-shrinkwrap-precedence

Conversation

@vianmangal

Copy link
Copy Markdown
Contributor

What changed

When package.json declares packageManager: "npm@...", root lockfile selection now keeps npm-shrinkwrap.json authoritative over package-lock.json. The package-manager override remains unchanged for pnpm, Yarn, and Bun projects.

Added a regression test covering both npm lockfiles with packageManager: "npm@11.0.0". It verifies that the shrinkwrap is scanned and the stale package-lock contents are ignored.

Why

The previous mapping always translated npm to package-lock.json. A project with both files could therefore scan an empty or stale package-lock and miss vulnerabilities recorded in the shrinkwrap.

Closes #1484

Verification

  • npm ci
  • npm run lint:tests
  • npm run build
  • node dist/index.js advisories sync
  • npm test -- --runInBand — 201 suites, 3,042 tests passed
  • node scripts/typecheck-changed-tests.mjs origin/main

@coderabbitai

coderabbitai Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Summary

Summary by CodeRabbit

  • Bug Fixes
    • When a project declares npm and includes both supported root lockfiles, package loading now uses npm-shrinkwrap.json rather than package-lock.json. This ensures the loaded packages reflect the shrinkwrap file, not potentially outdated package data. Other package managers continue to prefer their declared lockfile when available.

When package.json declares npm and both root npm lockfiles exist, the parser now selects npm-shrinkwrap.json. A regression test verifies the selected package content and the packageManager note.

Changes: Root npm lockfile selection

Layer / File(s) Summary
Select and verify the authoritative npm lockfile
src/parsers/index.ts, tests/parsers/load-packages.test.ts
When npm is declared and npm-shrinkwrap.json is present, the selector chooses it ahead of package-lock.json. The test checks that the shrinkwrap package is included, the stale package is excluded, and the result reports the declared package manager.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: High

Possibly related PRs

  • OWASP/cve-lite-cli#1448: This PR concerns use of the full lockfile graph from npm-shrinkwrap.json; this change ensures the root selector chooses that file when both npm lockfiles exist.
  • OWASP/cve-lite-cli#1446: This PR concerns the shrinkwrap SPDX fallback trigger; this change preserves shrinkwrap selection at the root when another npm lockfile is present.
Merge Risk: Minimal · up to 404b8

The change preserves npm shrinkwrap precedence and adds focused regression coverage without changing other package-manager selection behavior. No merge-blocking issue was identified.

Pre-merge checks: Passed 7
Check name Status Explanation
Title check Passed The title "fix(parsers): preserve npm shrinkwrap precedence" uses the required type prefix and lowercase style, has no trailing period, and names the main change: root lockfile selection now keeps npm…
Description check Passed The description follows the template's "What changed and why" heading and explains the change, the reason (the previous mapping always chose package-lock.json, which can miss shrinkwrap vulnerabilitie…
Linked Issues check Passed I find the coding requirements for #1484 met. findRootLockfile selects npm-shrinkwrap.json when npm is declared and that file is present. It preserves the declared-manager override for other manag…
Out of Scope Changes check Passed The reviewed changes stay within #1484. The source change updates root npm lockfile selection. The added test covers the reported npm declaration and both-lockfile case. No unrelated change is identif…
Linked Issue Passed The pull request body references GitHub issue #1484 with the supported keyword "Closes #1484".
Closes Keyword Matches Scope Passed The body uses “Closes #1484”. Issue #1484 asks for npm-shrinkwrap.json to remain authoritative when package.json declares npm and both npm lockfiles exist, plus a regression test. The diff implements …
No New Runtime Dependency Passed The pull request changes only src/parsers/index.ts and tests/parsers/load-packages.test.ts. The authoritative diff contains no package.json change, so it adds no runtime dependency and does not …
Full details: Title check

Explanation

The title "fix(parsers): preserve npm shrinkwrap precedence" uses the required type prefix and lowercase style, has no trailing period, and names the main change: root lockfile selection now keeps npm-shrinkwrap.json ahead of package-lock.json when package.json declares npm.

Full details: Description check

Explanation

The description follows the template's "What changed and why" heading and explains the change, the reason (the previous mapping always chose package-lock.json, which can miss shrinkwrap vulnerabilities), and the regression test. It also links issue #1484 and lists verification steps. The template's "Closes #" line is filled in with 1484. The section heading differs slightly from the template because the description uses separate "What changed" and "Why" headings instead of one combined heading. The content is complete.

Full details: Linked Issues check

Explanation

I find the coding requirements for #1484 met. findRootLockfile selects npm-shrinkwrap.json when npm is declared and that file is present. It preserves the declared-manager override for other managers. The regression test verifies the selected source, shrinkwrap package, excluded stale package, and npm package-manager note.

Full details: Out of Scope Changes check

Explanation

The reviewed changes stay within #1484. The source change updates root npm lockfile selection. The added test covers the reported npm declaration and both-lockfile case. No unrelated change is identified.

Full details: Closes Keyword Matches Scope

Explanation

The body uses “Closes #1484”. Issue #1484 asks for npm-shrinkwrap.json to remain authoritative when package.json declares npm and both npm lockfiles exist, plus a regression test. The diff implements that selection in src/parsers/index.ts and adds a test that verifies the shrinkwrap source and package, excludes the stale package-lock package, and records the npm packageManager note. The requested work is complete.

Full details: No New Runtime Dependency

Explanation

The pull request changes only src/parsers/index.ts and tests/parsers/load-packages.test.ts. The authoritative diff contains no package.json change, so it adds no runtime dependency and does not move any dependency from devDependencies.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.
Recent review info
Automatic approval policy

Commit: 404b86ac5ddc.

Setting Effective value Source
Automatic approvals Enabled Global configuration
Merge risk Moderate Global configuration
Security risk Not set Global configuration

No overrides matched. The global limits apply.

Not set means no limit was configured after inheritance. Use @coderabbitai configuration to inspect the resolved settings and their sources.

Run configuration
Commits

Reviewing files that changed from the base of the PR and between 280f098 and 404b86a.

Files selected for processing: 2
  • src/parsers/index.ts
  • tests/parsers/load-packages.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 2 remain after this review.

@sonukapoor

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@sonukapoor sonukapoor left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @vianmangal. I built a project where the shrinkwrap holds a vulnerable axios and package-lock.json holds only a clean package: with packageManager: npm declared, main reads package-lock.json and passes --fail-on high, and this branch reads the shrinkwrap and fails it. The JSON source, the SBOM and the fix command all follow the shrinkwrap too. Approved.

While checking it I found the same problem one level down: when the lockfiles sit in a single subfolder, the nested precedence list still ranks the shrinkwrap last. That's older than this PR, so I've filed it separately as #1494 rather than piling it on here.

Two optional things, no need to hold this for them:

  • Could we avoid the nested ternary that picks the npm lockfile? Mapping npm to both of its lockfiles in shrinkwrap-first order and taking the first one present would keep the rule in the package-manager table.
  • When the shrinkwrap wins, the note could say npm reads npm-shrinkwrap.json ahead of package-lock.json, since that is the actual reason, rather than the packageManager field.

@sonukapoor
sonukapoor merged commit 98ed40e into OWASP:main Nov 3, 2026
8 checks passed
@sonukapoor

Copy link
Copy Markdown
Collaborator

Merged - thank you @vianmangal!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] packageManager npm selects package-lock.json over npm-shrinkwrap.json

2 participants