A developer on your team runs npm install and pulls in a package one character off from the one they meant — discord.js instead of discordjs, crossenv instead of cross-env, electorn instead of electron. On npm, that single keystroke isn't a harmless typo. It's a direct line into a package that an attacker registered specifically to catch it, complete with a postinstall script that runs the moment npm install finishes — no click, no execution step, no warning.
This is npm typosquatting: registering package names that closely resemble popular ones, betting that human error or automated tooling will resolve to the malicious version. npm's registry has no name-similarity checks, no identity verification for new publishers, and over 3 million packages as of 2024 — a haystack large enough to hide thousands of look-alike names. Below, the mechanics, the real incidents, and what actually stops it.
What is npm typosquatting?
npm typosquatting is the practice of publishing a malicious package under a name that mimics a popular, legitimate package, so that a mistyped npm install command or a misconfigured dependency resolves to the attacker's code instead. The classic case is crossenv, published in 2017 to catch developers who meant to type cross-env, a build tool with roughly 1.5 million monthly downloads at the time. The malicious package ran a postinstall script that collected environment variables — including npm auth tokens and CI secrets — and shipped them to a remote server before npm removed it. It had already been downloaded several hundred times.
The attack works because npm executes install-time scripts (preinstall, install, postinstall) by default, unlike registries that require an explicit run step. A typosquat doesn't need the victim to import a function or call an API — it just needs to finish installing.
How do attackers pick names that get installed by mistake?
Attackers use a small, repeatable set of naming tricks that exploit predictable typing errors, not creativity. The four most common patterns on npm are:
- Character omission — dropping a letter, as in
expresforexpressorreqeustforrequest. - Character transposition or substitution — swapping adjacent letters or nearby keyboard keys, as in
lodahsoraxoisforaxios. - Hyphen and word-boundary confusion — removing or adding a hyphen, exactly how
crossenvtargetedcross-env. - Combosquatting — appending a plausible-sounding suffix to a real name, like
react-router-dom-v6orbabel-cli-utils, which reads as legitimate rather than as a typo at all.
A fifth npm-specific variant is scope confusion: publishing an unscoped package (babel-core-utils) to imitate a scoped one (@babel/core-utils), since npm treats scoped and unscoped names as entirely separate namespaces with no cross-checking. Academic analysis of open-source supply chain attacks — including the 2020 "Backstabber's Knife Collection" study, which catalogued 174 malicious open-source packages across npm, PyPI, and RubyGems — found typosquatting was the single most common distribution technique attackers used to get malicious code executed on developer and CI machines.
What are real examples of npm typosquatting on record?
Beyond crossenv, npm typosquatting has escalated from lone-wolf attacks to state-linked and financially motivated campaigns operating at volume. In 2023 and 2024, researchers at Phylum and Datadog documented a campaign now tracked as "Contagious Interview," attributed to North Korean threat actors, in which fake recruiters sent software developers "coding test" repositories that pulled in npm packages with names crafted to look like legitimate testing or utility libraries. The payload was a credential-stealing backdoor (variants tracked as BeaverTail and InvisibleFerret), and the campaign specifically targeted job-seeking developers because they install unfamiliar packages from strangers as a matter of course.
At the volume end, Sonatype's 2023 State of the Software Supply Chain report identified 245,032 malicious open-source packages across ecosystems that year — more than double every prior year combined — with typosquatting and dependency confusion cited as the two dominant distribution techniques on npm specifically. JFrog researchers separately identified batches of over 180 malicious npm packages published within days of each other in 2021, using automated scripts to generate and register typo variants of popular names in bulk rather than crafting them by hand. The pattern across every documented case is the same: register the name, add a postinstall hook, wait for the mistake.
Why is npm particularly exposed to this kind of attack?
npm is exposed because its registry optimizes for frictionless publishing, not name integrity, and that design choice is structural rather than a bug to be patched. Anyone can register an unclaimed package name in seconds with no proof of affiliation to the project they're imitating, no manual review, and no automated similarity check against existing high-download packages at publish time.
Two npm-specific mechanics make the exposure worse than it would be on a more locked-down registry. First, install scripts run automatically and by default — a typosquat's payload executes during npm install, before a human ever opens a text editor or reads a line of the package's code. Second, npm's dependency graphs are deep: a single package.json can pull in hundreds of transitive dependencies, and a typosquatted package doesn't need to be the one your engineer typed — it only needs to be pulled in by a tool, script, or transitive dependency somewhere in that tree, where nobody is reading names character by character. CI/CD pipelines compound the risk further: an automated npm ci run doesn't pause to notice a name looks slightly wrong the way a human occasionally might.
How can developers and organizations actually catch npm typosquats?
The most reliable defense is a layered one: lockfiles, install-script restrictions, and automated name-similarity checks, applied before a package ever reaches a build. package-lock.json pins exact resolved versions and prevents silent drift to a different package on a re-install, but it does nothing to stop the initial mistaken npm install <typo> — that has to be caught before the lockfile is written.
Concrete steps that close the gap:
- Run
npm install --ignore-scriptsin CI so a malicious postinstall hook never executes even if a bad package slips through. - Check registry metadata before adding an unfamiliar dependency:
npm view <package> time.created maintainerstakes one command and immediately surfaces a package published last week by a maintainer with no other packages — a near-certain red flag when the name resembles something popular. - Route installs through a proxy registry (Artifactory, Nexus, or Verdaccio) with an allowlist, so unreviewed package names can't reach developer machines or build agents at all.
- Run Levenshtein-distance checks in a pre-commit hook or CI job against a curated list of your organization's actual top-level dependencies — most real typosquats sit at edit-distance 1 or 2 from the name they're imitating.
None of these controls fully replace human attention, but together they turn a single mistyped keystroke from an unrecoverable compromise into a blocked pull request.
How Safeguard Helps
Safeguard checks every package name in your SBOM and dependency manifests against a curated corpus of high-download packages and known typosquatting incidents, flagging low-reputation names that sit one or two edits from a package you actually depend on — before they reach a build. Griffin AI then applies reachability analysis to prioritize what's found: a flagged package sitting in a dev-only dependency path is triaged differently than one that's actually imported and reachable from your production code, so teams aren't drowning in equal-priority alerts for unequal risk. Safeguard ingests SBOMs from your existing pipelines (or generates them directly via CLI and CI integration) so this check runs continuously, not just at audit time, and a typosquat flagged in one part of your organization is recorded so it auto-blocks everywhere else. When a suspicious dependency is confirmed, Safeguard can open an auto-fix pull request that reverts to the legitimate package or pins a known-good version, so remediation doesn't wait on someone noticing the alert.