Severity: medium · Action: replace (or suggest if no installed version)
An override whose pin value is a floating tag or a non-semver string:
| Pin value | Why it's floating |
|---|---|
"latest" |
Reinterpreted on every install |
"next" |
Pre-release channel; cuts new versions arbitrarily |
"*" |
Matches anything |
"x" |
Same as * in npm semver |
"" (empty) |
npm treats as * |
Anything semver.validRange rejects |
e.g. typos like ^v1.0.0, registry shorthand, git URLs |
It also fires on invalid semver ranges that semver.validRange cannot parse. They would either be coerced or rejected at install time, but they make the intent of the pin unreadable.
Output:
MEDIUM (1)
----------
OA002 @esbuild/linux-x64
package.json/overrides/@esbuild~1linux-x64
Override pinned to floating tag
fix: applyable patch (1 op)
Overrides usually exist to fix a specific CVE or force a minimum-safe version. A floating tag undermines both jobs:
- A future install could resolve
latestto a version that's actually older than the one that was current when the override was written (rare, but possible during patch back-merges and reverts). - More commonly,
latestresolves to a new major that breaks the consumer that depended on the lower major: exactly the failure mode an override was meant to prevent.
The pattern is especially insidious in security-driven pins, where the author intended latest to mean "always the newest, so always safe." In practice, >=X.Y.Z is the durable encoding of that intent.
OA002 will not flag:
workspace:*/workspace:^(pnpm workspace protocol)file:../path(local file dependency)link:../path(symlinked dependency)npm:<alias>@<range>(registry aliases: the version selector lives after the alias, not in the pin string)- Nested-object override values (those are OA005's territory)
cve-lite overrides --fix --rule OA002--fix emits a single-op replace patch swapping the floating tag for >=<installed-version> when the package is installed under node_modules. If it isn't installed yet, the finding stays suggest-only (no patch attached): install dependencies first, then re-run --fix.
The proposed replacement is >=<installed-version>: a floor, not a ceiling. This:
- Encodes "at least this version, for security" semantics.
- Lets pnpm/npm pick the newest compatible version on install.
- Doesn't lock the consumer out of legitimate patch and minor updates.
If node_modules/<package>/package.json is missing (project hasn't been installed yet), the finding is emitted without a fix patch and the message advises installing dependencies and re-running.
Almost never for production overrides. If your project is itself a starter kit or scaffold that should float with upstream, drive the override-floor convention elsewhere (e.g. a publish-time script that pins to the most recent version at publish).
src/overrides/detectors/oa002-floating-tag.ts- npm-package-json
overrides. None of these doc pages caution against floating tags.
{ "overrides": { "@esbuild/linux-x64": "latest", // <- floats with every install "postcss": "8.5.x", // valid range, NOT flagged "react": "^18.0.0" // valid range, NOT flagged } }