Dependency Confusion Attack: How It Works and How to Prevent It
In 2021, security researcher Alex Birsan discovered that he could compromise internal systems at Apple, Microsoft, PayPal, Shopify, and over 35 other companies using a single technique: publishing public npm packages with the same names as the companies' private internal packages. npm installed the attacker's version automatically — no phishing, no credential theft, no social engineering required. The technique is called dependency confusion, and it remains an active threat for any team using private package registries alongside npm.
What Is a Dependency Confusion Attack?
A dependency confusion attack exploits how package managers resolve names when both a private registry and the public npm registry are configured. When an attacker publishes a package with the same name as a private internal package at a higher version number, npm installs the public attacker-controlled version instead of the legitimate internal one — without any human error triggering the substitution.
The attack works because most npm configurations that include a private registry still fall back to the public registry for any package not found internally. The resolution order is: check private registry → if not found, check public npm registry. An attacker who knows an internal package name can claim that name on the public registry, set a higher version number than the internal package, and wait for developers or CI/CD pipelines to run npm install.
The most dangerous version of the attack installs a maliciouspostinstall script that executes automatically during installation — no developer needs to import or call the package for the payload to run. The postinstall script runs with the permissions of the user who ran npm install, giving attackers immediate access to the developer's machine, environment variables, and any credentials accessible from the terminal session.
How Does Dependency Confusion Differ from Typosquatting?
Dependency confusion uses the exact same package name as the target internal package — the attack exploits registry resolution order, not name similarity. Typosquatting uses a name one or two characters different from a popular package to catch manual installation errors. Dependency confusion is automatic and requires no developer mistake to succeed.
This distinction matters for detection. Typosquatting is caught by comparing package names against a list of popular packages using edit-distance calculations — a name within one character oflodash or axios is suspicious. NPM supply chain attack detection covers this attack vector using Levenshtein distance matching. Dependency confusion requires a different detection approach: identifying packages that appear to use internal naming conventions (scoped packages, company-prefixed names, or names matching internal registry patterns) but resolve to the public registry.
A third related attack — namespace confusion — targets scoped packages. An attacker publishes @evilcorp/legitimate-tool to confuse developers who expect @company/legitimate-tool. This combines elements of both typosquatting (similar scope name) and dependency confusion (registry resolution exploitation).
How Do Attackers Execute a Dependency Confusion Attack?
Attackers execute dependency confusion attacks by first identifying private package names — from leaked package.json files in public repositories, job postings referencing internal tooling, or npm error messages that reveal private package names. They then publish a package with the same name to the public registry at a version higher than the internal one, with a malicious postinstall script.
Package name discovery is the first step. Internal package names leak in many ways: developers commit package.json files to public GitHub repositories without realizing they reference private scoped packages, npm error logs in public CI/CD pipeline outputs reveal packages that failed to resolve, and job postings occasionally reference internal tooling by name. Security researcher Alex Birsan found names by examining public error logs and build artifacts from targeted companies.
Once the name is known, the attack is fast. Publishing to npm takes minutes. The malicious package sets a version like9999.0.0 — high enough to win any version comparison against the internal package. The postinstall script typically runs a reverse shell, exfiltrates environment variables via a DNS lookup (which bypasses many egress filters), or installs persistence mechanisms on the developer's machine.
Which Companies Have Been Hit by Dependency Confusion?
Apple, Microsoft, PayPal, Shopify, Netflix, Uber, Yelp, and over 35 other large companies were successfully compromised by Alex Birsan's 2021 dependency confusion research. All installations were from legitimate developer machines or CI/CD pipelines running standard npm install — no credentials were stolen to gain initial access.
Birsan published his findings as responsible disclosure research, earning over $130,000 in bug bounties across the affected companies. His technique demonstrated that supply chain attacks could bypass perimeter security entirely by targeting the development workflow itself. The finding prompted npm to add publishConfig enhancements and scoped registry pinning to its recommended security practices.
The companies affected were not negligent — they had private registries, security teams, and standard development practices. The attack succeeded because it exploited a design assumption in package manager resolution that nobody had examined as a security boundary.
How Can Developers Prevent Dependency Confusion Attacks?
Developers prevent dependency confusion by configuring npm to pin all scoped packages to the private registry, publishing placeholder packages on the public registry to claim internal names, using npm's publishConfig to restrict where packages can be published, and auditing all new packages in CI/CD before installation.
The most reliable prevention is registry pinning: configure .npmrc so that all packages under your private scope resolve exclusively to your private registry, never falling through to the public one. For Verdaccio, Artifactory, or GitHub Package Registry, this means setting @company:registry=https://your-registryin .npmrc rather than relying on fallback resolution order.
Claiming names on the public registry is a defensive measure, not a solution. Publishing a 1.0.0 placeholder with no content under your internal package names prevents attackers from registering the same names — but it requires maintaining a registry of all internal package names and publishing proactively before a name leaks.
For teams using AI coding assistants, dependency security scanning in VS Code catches issues at the editor level before a developer runs npm install. AI coding tools occasionally suggest packages that mix internal naming conventions with public availability — a pattern that looks identical to a dependency confusion setup from the scanner's perspective.
How Does Vibe Owl Detect Dependency Confusion Risks?
Vibe Owl's Pro Dependency Intelligence cross-references package names in your manifests against publication metadata — flagging packages that were published within the last seven days, have zero prior downloads, or match patterns consistent with private package naming conventions appearing on the public registry for the first time.
The detection runs locally in VS Code and Cursor without sending manifest data to any external service. When a suspicious package is flagged, the finding appears as an inline diagnostic in the editor alongside the package.json entry — the same way a type error appears in TypeScript — giving the developer an immediate visual signal before running npm install.
Dependency confusion is one of several npm supply chain attack vectors covered by Vibe Owl's dependency scanning. Typosquatting, malicious postinstall scripts, and lockfile tampering are detected alongside confusion attacks, giving a complete view of the dependency surface from inside the editor rather than after a CI/CD pipeline run.
The full threat model for developer-facing supply chain security — from typosquatting through dependency confusion through hallucinated package names from AI tools — is covered in the vibe coding security guide.