minimist is one of the most-depended-upon packages in the npm ecosystem — a lightweight command-line argument parser pulled in, directly or transitively, by tools like mkdirp, optimist, and countless build scripts and CLIs. CVE-2021-44906 documents a prototype pollution vulnerability in minimist versions prior to 1.2.6: an attacker who can influence the arguments (or an equivalent object) passed into minimist's parser can inject keys such as __proto__ or constructor.prototype and pollute Object.prototype for the entire running process. Because prototype pollution corrupts a shared, global object, the practical impact ranges from denial of service to, in vulnerable downstream code paths, property injection that enables authentication bypass or even remote code execution.
What makes this CVE notable isn't novelty — it's persistence. Minimist had already shipped one prototype pollution fix (tracked separately as CVE-2020-7598) years earlier. CVE-2021-44906 exists because that earlier mitigation was incomplete: researchers found that the parser's key-assignment logic could still be coerced into writing to the prototype chain through slightly different payload shapes. It's a textbook example of why supply-chain risk isn't a one-time patch-and-forget exercise — a "fixed" transitive dependency can still be carrying an unpatched variant of the same bug class.
Affected Versions and Components
- Package:
minimist(npm) - Vulnerable versions: releases prior to 1.2.6
- Fixed version: 1.2.6, which hardens the argument-parsing logic against
__proto__andconstructor.prototypekey injection - Exposure path: minimist is rarely installed directly by application developers; it is far more commonly pulled in as a transitive dependency of build tooling and other npm packages (historically including
mkdirp,optimist, and other CLI-adjacent libraries). This is what turned a small parser bug into a wide-reaching advisory — many teams had no idea minimist was in their dependency tree at all until scanners flagged it. - Attack precondition: an application must pass attacker-influenced input into minimist's parsing functions (or otherwise expose the argument object to untrusted data) for the pollution to be reachable. Command-line tools that parse only trusted, operator-supplied arguments carry materially lower real-world risk than services that pass user-controlled data through minimist-based parsing.
CVSS, EPSS, and KEV Context
Public vulnerability databases and dependency scanners (NVD, GitHub Security Advisories, Snyk) list CVE-2021-44906 with a CVSS v3.1 base score of 9.8 (Critical), reflecting a network-exploitable, low-complexity, no-privilege-required path to a high-impact confidentiality/integrity/availability outcome — the standard scoring pattern for prototype pollution issues that can cascade into property injection or RCE in the right application context.
That headline score should be read with the usual caveat for prototype pollution CVEs: the base score assumes a maximally exploitable downstream context, but the actual exploitability for any given application depends entirely on whether attacker-controlled data reaches the vulnerable parsing call and whether polluted prototype properties are later consumed in a dangerous way (e.g., in an if (obj.isAdmin) check or a template-rendering path). Two applications with the identical vulnerable minimist version can have wildly different real-world risk.
On exploitability signals: we're not going to quote a specific EPSS percentile here, since EPSS scores are recalculated regularly and any number we printed today would likely be stale by the time you read this — check the current score directly at FIRST.org's EPSS API or your scanner's live feed rather than trusting a static figure in a blog post. As of this writing, CVE-2021-44906 does not appear on CISA's Known Exploited Vulnerabilities (KEV) catalog, meaning there's no confirmed evidence of active in-the-wild exploitation tracked by CISA — but KEV absence is not a safety signal, particularly for a library with minimist's dependency footprint. Absence from KEV simply means no confirmed campaign has been attributed to this specific CVE; it doesn't mean the pollution primitive isn't being chained into other attacks.
Timeline
- Minimist previously patched a related prototype pollution issue, later tracked as CVE-2020-7598, establishing
__proto__key filtering in the parser. - Security researchers subsequently found that the CVE-2020-7598 fix did not cover all payload variants, allowing prototype pollution to be reintroduced through alternate key structures.
- The maintainer shipped minimist 1.2.6, closing the gap by more comprehensively rejecting dangerous prototype-chain keys during argument parsing.
- The issue was assigned CVE-2021-44906 and published to NVD and GitHub Security Advisories, where it has since been surfaced repeatedly by SCA tools, Dependabot, and
npm auditacross the ecosystem — often as a nested, hard-to-untangle transitive finding rather than a direct dependency flag.
Because minimist sits so deep in so many dependency trees, this advisory has had an unusually long tail: years after the fix shipped, security teams still routinely find outdated minimist copies nested three or four levels deep in lockfiles, pulled in by an unrelated top-level package that itself hasn't bumped its own dependency pin.
Remediation Steps
- Identify exposure. Run
npm ls minimist(or the Yarn/pnpm equivalent) across every service and monorepo package to find every resolved copy, including nested transitive instances — a singlepackage.jsoncan end up with multiple minimist versions coexisting at different depths. - Upgrade to 1.2.6 or later. Where minimist is a direct dependency, bump it explicitly. Where it's transitive, update the parent package to a version that pins a patched minimist, or use your package manager's override mechanism (
overridesin npm,resolutionsin Yarn,pnpm.overridesin pnpm) to force the resolved version without waiting on every upstream maintainer. - Regenerate and commit lockfiles after the override so CI and every developer machine resolve to the patched version consistently — a partial fix that only lives in one engineer's
node_modulesprovides no real protection. - Audit application-level handling of parsed arguments for unsafe patterns, such as merging parsed CLI output directly into configuration objects or using it to set properties dynamically. Even with minimist patched, defense-in-depth against prototype pollution (e.g.,
Object.freeze(Object.prototype)in sensitive processes, or usingMapinstead of plain objects for untrusted key-value data) reduces blast radius from future pollution bugs in other dependencies. - Re-run SCA scans post-remediation to confirm no nested copy of the vulnerable version survived the override — override syntax mistakes are a common reason teams believe they've patched when a stale transitive copy is still resolving.
- Add minimist (and its common carriers) to your dependency-freshness monitoring so future advisories on this package — or on
optimist,mkdirp, and other frequent transitive consumers — are caught automatically rather than rediscovered during an incident.
How Safeguard Helps
CVE-2021-44906 is a good illustration of why supply-chain security has to be continuous rather than point-in-time. A one-off npm audit run during a release cycle can easily miss a minimist copy that's four dependency hops deep, especially in large monorepos where lockfiles diverge across packages. Safeguard's software supply chain security platform is built for exactly this class of problem:
- Full-depth dependency graph visibility, so nested and transitive instances of vulnerable packages like minimist are surfaced regardless of how deeply they're buried in your tree — not just the direct dependencies your manifest lists.
- Continuous monitoring, so when a package you already ship gets a new advisory — or when an old advisory like this one resurfaces via a new transitive path — you're notified automatically instead of finding out during your next manual audit.
- Reachability-aware risk scoring, which helps separate "technically vulnerable dependency present" from "attacker-controlled input can actually reach the vulnerable code path," so teams can prioritize the minimist instances that matter most instead of treating every hit with the same urgency as the CVSS base score implies.
- Guided remediation, including override/resolution recommendations, so fixing a deeply nested transitive vulnerability doesn't require manually tracing which top-level package needs to bump its own pin.
Prototype pollution bugs like CVE-2021-44906 rarely announce themselves loudly in production — they surface as subtle logic bypasses or unexplained crashes long after the vulnerable code shipped. Closing that gap starts with knowing, continuously and precisely, what's actually in your dependency tree.