fix: treat a pre-release of the introduced version as in range - #1098
Merged
Conversation
…ange Making compareVersions semver-correct in #1084 fixed the upper bound of an affected range but broke the lower one. A pre-release sorts below its release, so an install of 1.2.0-beta.1 fell outside a range introduced at 1.2.0 and stopped being reported. In practice that build is a pre-release of 1.2.0 and carries whatever the advisory says was introduced there, so excluding it is a false negative in the opposite direction from the one #1084 fixed. versionMatchesRange now treats a version as at or above the introduced bound when it is a pre-release whose release core equals that bound. compareVersions is untouched: it is used for sorting throughout the codebase and must stay spec-correct. The relaxation deliberately cannot widen a pre-release lower bound. OSV declares plenty of those: 64 of 352 introduced events across 15 sampled packages, with Next.js using values like 15.0.1-canary.0 routinely. Those are precise canary boundaries, and widening them would pull in earlier canaries the advisory excluded, trading this false negative for a false positive. No guard is needed because a release core never contains a hyphen, so it can never equal a pre-release bound. Verified end to end against a real offline advisory database: main reports "No known vulnerabilities found" for a vulnerable pre-release install, this branch flags it and emits a working fix command. Closes #1086
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Making
compareVersionssemver-correct in #1084 fixed the upper bound of an affected range but broke the lower one. A pre-release sorts below its release, so an install of1.2.0-beta.1fell outside a range introduced at1.2.0and stopped being reported. That build is a pre-release of1.2.0and carries whatever the advisory says was introduced there, so excluding it is a false negative in the opposite direction from the one #1084 fixed.versionMatchesRangenow treats a version as at or above theintroducedbound when it is a pre-release whose release core equals that bound.compareVersionsis untouched: it is used for sorting throughout the codebase and must stay spec-correct.Why the relaxation stops where it does
The issue originally proposed comparing the lower bound against the release core. Checking real OSV data first ruled that out. Across 15 sampled npm packages, 64 of 352
introducedevents are themselves pre-releases, and Next.js does it routinely:Widening those to their release core would pull in earlier canaries the advisory explicitly excluded, trading this false negative for a false positive on the highest-profile package in our advisory set. So the relaxation applies only when the bound is a stable release. No explicit guard is needed: a release core never contains a hyphen, so it can never equal a pre-release bound.
Verification
Before and after, through the real CLI against a real offline advisory database seeded with
demo-pkg [1.2.0, 1.3.0), scanning an install ofdemo-pkg@1.2.0-beta.1:19 tests in
local-advisory-source.test.ts, covering the stable-boundary case, thelast_affectedinteraction, and four Next.js canary shapes that must keep comparing exactly. Removing the relaxation fails two of them.Scope
Offline only.
versionMatchesRangelives inlocal-db.ts; the online path goes through the OSV API, which does its own range matching. Affects--offlineand--offline-db.Like #1084 and #1085, this makes offline scans report more findings for pre-release installs. Anyone on a canary or rc with a
--ratchetbaseline may see new findings and need to regenerate. Already noted in the release tracker.Closes #1086