· via dev.to (home feed)
How npm typosquatting and dependency confusion slip past CVE scanners
A dev.to explainer covers typosquatting and dependency confusion, two supply-chain attacks that exploit package-name resolution rather than code flaws, and the detection signals and registry settings that stop them.

Supply-chain attacks against JavaScript developers do not always require an exploitable bug. A walkthrough on dev.to explains two classes of attack — typosquatting and dependency confusion — that abuse how package managers resolve names rather than any flaw in the code itself, which is exactly why scanners built around CVE databases tend to miss them.
The article opens with the best-known demonstration of the technique. In February 2021, security researcher Alex Birsan published a write-up showing how he had pushed malicious packages into the internal build systems of Apple, Microsoft, PayPal, Shopify and 32 other companies. He compromised no servers, exploited no known vulnerability and sent no phishing mail; he simply published packages to npm, PyPI and RubyGems whose names matched internal packages those companies relied on, and their build tooling installed his public versions automatically.
Typosquatting targets the keyboard
Typosquatting takes advantage of the fact that developers type package names by hand. An attacker registers a name such as expresss — one extra letter — and anyone who makes that slip during install pulls down the attacker's code. Dress the package up with a plausible README and a few hundred bot-driven weekly downloads and it blends in. The payload usually lives in a postinstall script, which npm executes during installation, before anyone has had a chance to read the code. Such a script can read environment variables full of API keys and tokens, plant persistent backdoors or alter other packages already present in node_modules.
The dev.to piece points to real incidents from npm's history: crossenv, a lookalike of cross-env that harvested environment variables; getcookies, which exfiltrated browser cookies; loadsh, a near-miss of lodash; and reqeusts and reqests, variants of Python's requests library.
Dependency confusion targets the registry
Dependency confusion works on a different logic error. Companies commonly run a private npm registry — Artifactory, Nexus or GitHub Packages — alongside the public one, and typical configurations fall back to the public registry when the private one lacks a package, or pick whichever copy carries the higher version number. An attacker who learns an internal package name, often from job postings, leaked configuration files or error messages, publishes a public package under that name at an inflated version such as 99.0.0 and waits for build systems to prefer it.
The remediation the article recommends is to place all internal packages under a private scope, for example @company/internal-lib rather than internal-lib, and configure the registry so scoped packages resolve only from the private registry. That is deliberate configuration work, and the author notes many teams have never gotten around to it.
The signals that precede any CVE
Because neither attack involves a vulnerability in a published package, there is no CVE to match against. According to the article, the indicators that matter instead are:
- Edit-distance checks (Levenshtein or Damerau-Levenshtein) that flag dependencies sitting one keystroke away from lodash, express or react while having no established publishing history.
- Install scripts, which legitimate packages rarely need; a recent, unknown package carrying a postinstall script deserves scrutiny.
- Freshness and maintainer signals — a package published days ago with zero dependents that mimics a popular name is almost certainly malicious or a test, while a maintainer handover on an established package echoes the XZ Utils backdoor mechanism.
- Version anomalies, such as a leap from 1.0.4 to 99.0.0, a classic dependency-confusion fingerprint.
The author's own tool, DepWarden, applies a Damerau-Levenshtein comparison against a curated list of the most popular packages in each ecosystem and raises a high-severity supply-chain finding that names the package a suspect resembles. It also surfaces install scripts, maintainer changes and version anomalies drawn from OpenSSF Scorecard and supply-chain metadata. The article closes by pointing to an accompanying analysis that checked every single-character variant of the 30 most popular npm and PyPI package names against the live registries and cross-referenced the hits with OSV's malicious-package database.
Why it matters
Both attack classes execute before a CVE is ever filed — if one is filed at all. By the time a lookalike package earns a CVE, its postinstall script has already run on developer machines and CI runners. That shifts the burden of defence upstream of vulnerability databases: verify names before installing them, lock internal packages behind a private scope, and treat behavioural signals like install scripts, maintainer churn and odd version jumps as first-class findings rather than noise.
- #npm
- #supply-chain-security
- #javascript
- #package-management
- #security