semver is the reference implementation of Semantic Versioning for JavaScript. It parses version strings, compares them, and — most importantly — evaluates range expressions like ^1.2.0 or >=2.0.0 <3.0.0 to decide whether a version satisfies a constraint. npm itself uses it, and so does effectively every package manager, dependency resolver, CI tool, and framework in the Node.js world. On npm it is one of the highest-volume downloads in existence, almost always arriving transitively. Because its whole job is turning strings into structured version data using regular expressions, its one notable security issue is exactly the kind you would predict: a regular-expression denial of service in the range parser. That single CVE appeared in a vast number of dependency trees, which is why "upgrade semver" became a familiar line item across the ecosystem.
The notable historical CVEs
semver's headline advisory is a ReDoS — a regular expression whose backtracking blows up on a crafted input, letting a small string pin a CPU core for a long time:
- CVE-2022-25883 — the
new Rangecode path (and the functions built on it, such as coercion and satisfaction checks) used a regular expression vulnerable to catastrophic backtracking when handling range strings with unusual whitespace and structure. An attacker who can supply an untrusted range string can make the parse take exponential time, stalling the event loop and denying service. It is fixed in7.5.2on the7.xline,6.3.1on the6.xline, and5.7.2on the5.xline — the fix was backported across all three maintained branches precisely because so many projects were pinned to older majors.
That branch-wide backport is the detail that trips teams up: knowing "semver is patched" is not enough, because a dependency tree frequently resolves several major versions of semver at once, and each one needs to be on its own patched release.
Common misuse and risks
- Passing untrusted strings to range functions. The risk in CVE-2022-25883 is realized when attacker-influenced input reaches
new Range,satisfies,coerce, or similar. A service that accepts a version or range from an API request, a registry query, a webhook payload, or a user-supplied manifest and feeds it straight into semver is exposed to the ReDoS. - Treating version parsing as trivial and unbounded. Because semver "just parses versions," code often calls it on external input with no length cap or timeout, which is exactly what a ReDoS needs.
- Multiple stale majors in one tree. A lockfile commonly contains semver
5.x,6.x, and7.xsimultaneously at different depths. Upgrading the top-level one leaves the others vulnerable. - Deeply transitive exposure. semver is almost never a direct dependency, so a vulnerable copy can persist behind an intermediate package's loose range long after you believe you have upgraded.
How to use semver safely
Set the version floor: run semver 7.5.2 or later on the current line, or 6.3.1 / 5.7.2 if you are still on an older major. Those are the releases that fixed the range-parser ReDoS, and because the change is internal to the regex, the upgrade is behavior-compatible in practice.
Then contain the input:
- Never parse an untrusted range without bounds. If a user or remote system can supply a version or range string, cap its length before parsing and reject obviously malformed input early. A patched semver removes the catastrophic backtracking, but length limits are cheap defense-in-depth.
- Prefer strict parsing for external input. When you only need to validate a concrete version (not a range), use the stricter
valid/parseentry points rather than the more permissive range machinery. - Deduplicate the tree. Run
npm ls semver(or the yarn/pnpm equivalent) after upgrading to confirm every resolved copy — across all majors — is on a patched release, and use overrides/resolutions to lift stubborn transitive pins. - Pin and monitor. Commit a lockfile so a loose semver range cannot silently reintroduce a vulnerable version.
How to monitor semver with SCA and reachability
semver is the archetypal universal transitive dependency: a scanner will flag it in nearly every Node.js project, frequently in several major versions at once. The bare finding tells you it is present; what matters is whether untrusted input actually reaches a range function, and whether each resolved copy is patched.
Safeguard's software composition analysis resolves your entire npm dependency graph, surfaces every semver version in the tree, and adds call-path reachability so a ReDoS advisory sitting on a real, attacker-reachable parsing path is separated from a copy that only ever parses trusted, developer-authored version strings. When a bump is warranted, autonomous auto-fix opens a tested pull request — including the overrides to raise old majors — and Griffin AI explains whether a given copy is exploitable. Developers run the same analysis locally and in CI with the Safeguard CLI, and teams comparing tools can review the pricing.
Bring continuous, prioritized dependency analysis to your Node.js services — get started free or read the documentation.
Frequently Asked Questions
Which semver version is safe in 2026?
Run semver 7.5.2 or later on the current line. If a dependency pins you to an older major, the ReDoS fix (CVE-2022-25883) was backported to 6.3.1 on the 6.x line and 5.7.2 on the 5.x line, so make sure every copy in your tree is on one of those patched releases — a single lockfile often carries all three majors at once.
What is ReDoS and why does it affect semver?
ReDoS is regular-expression denial of service: a pattern with catastrophic backtracking takes exponential time on a crafted input, letting a small string consume a CPU core. semver's range parser used such a pattern, so an attacker who supplies an untrusted range string could stall the event loop until the process is effectively hung.
Is semver safe if I only parse my own version strings?
The practical risk is low when every version and range string comes from trusted, developer-authored sources, but you should still upgrade to a patched release. The exposure appears when attacker-influenced input — from an API request, a manifest upload, or a registry query — reaches a range function like new Range, satisfies, or coerce.
How do I know if a semver CVE actually affects my app?
Use reachability-aware SCA. It enumerates every semver copy in your dependency tree and traces whether untrusted input reaches a range-parsing call, so you can prioritize a genuinely reachable, unpatched copy over one that only parses trusted version strings deep inside a build tool.