Skip to content

fix(arborist): allow audit fix to install safe downgrades#9761

Open
martinrrm wants to merge 1 commit into
latestfrom
fix/audit-safe-downgrade
Open

fix(arborist): allow audit fix to install safe downgrades#9761
martinrrm wants to merge 1 commit into
latestfrom
fix/audit-safe-downgrade

Conversation

@martinrrm

Copy link
Copy Markdown
Contributor

What / Why

npm audit can report that a fix is available through npm audit fix when the highest safe version inside the declared dependency range is older than the installed version.

Arborist already selects that safe candidate using the advisory range, but CanPlaceDep rejects it because replacement candidates normally must be newer than the installed version. This causes npm audit fix to complete without applying the advertised remediation.

How

  • Pass the existing audit report from PlaceDep into CanPlaceDep and recursive peer placement checks.
  • Permit an older candidate only when:
    • the installed node is vulnerable;
    • the candidate is not vulnerable; and
    • the candidate passes the existing replacement and peer dependency checks.
  • Preserve existing no-downgrade behavior for ordinary installs and updates.
  • Add synthetic, strictly mocked regressions covering:
    • compatible safe downgrades;
    • non-audit placement;
    • still-vulnerable candidates;
    • peer conflicts;
    • actual tree replacement; and
    • metavulnerability removal by pruning a vulnerable transitive dependency.

This does not change audit reporting or --force behavior. Fixes outside declared dependency ranges still require npm audit fix --force.

Testing

  • Focused Arborist placement and audit tests
  • npm command-level audit tests

References

Fixes #9557
Fixes #9718

`npm audit fix` can select an older non-vulnerable version that still
satisfies the declared dependency range, but `CanPlaceDep` rejects it
because replacement candidates normally must be newer than installed.

Pass the audit report into placement checks and allow an older candidate
only when it replaces a vulnerable node with a non-vulnerable one.
Existing replacement and peer checks still determine whether placement
is valid, and non-audit installs keep the existing no-downgrade behavior.

Add placement and mocked audit regressions for compatible downgrades,
metavulnerability pruning, vulnerable candidates, and peer conflicts.

## References

Fixes #9557
Fixes #9718

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7e9acf04-45ee-4afc-b3b0-091b0165e68b
@martinrrm martinrrm requested review from a team as code owners July 13, 2026 20:30
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] npm audit prints fix available via npm audit fix, but it doesn't fix anything [BUG] npm audit fix does nothing

1 participant