Home / Knowledge hub / Dependency confusion
Knowledge hub
Dependency confusion
Tricking a build into fetching a public package that shares a private package's name.
What it means
Dependency confusion is a supply chain attack where someone publishes a public package with the same name as one of your private, internal packages. If your build tool looks in both places and prefers the public one, it installs the attacker's code instead of yours.
The trick relies on version numbers. Many package managers, when asked for a name found in more than one registry, choose the highest version. The attacker publishes a very high version number, and the build picks it up on its own, with no one making a mistake that day.
Why it matters
Package installation often runs code, so the attacker's code can execute on developer laptops and build servers. Those machines hold source code, cloud credentials and signing keys. The security researcher Alex Birsan showed in 2021 that this worked against many large companies.
The attacker needs only the names of your internal packages, which leak in public files and error messages. It is one of several routes in supply chain attacks, close to typosquatting, and it hits the build before any product test could.
How it shows up
You meet it wherever a project installs from both a private registry and a public one, in package.json, requirements files and similar. Repeated causes are internal package names that are not reserved publicly, a registry setup that falls back to the public source, and builds that resolve versions fresh each time.
Use scoped or namespaced names you own, configure the client to fetch internal names only from the private registry, reserve your names on public registries, and commit a lockfile with integrity hashes. Check what each build actually resolved, not what the file says it should have resolved, and alert when an internal name resolves from a public source.
Questions people ask
Dependency confusion, answered
How is dependency confusion different from typosquatting?
Typosquatting relies on a developer mistyping a name. Dependency confusion needs no mistake: the build tool itself picks the public package because it shares the exact name of a private one.
Which package managers are affected?
Any that can look in more than one registry and choose by version, which has included npm, pip and others depending on configuration. Settings and safeguards vary by tool, so check yours.
How do we find out whether we are exposed?
List your internal package names, check whether each exists on the public registries, and look at how your clients are configured to resolve names. A public package with your internal name is a sign to investigate.
Do scoped packages solve it?
Scopes in npm, for example, tie a name to an owner, so another party cannot publish under your scope. Claim the scope on the public registry, and make sure all of your internal packages use it from the start.
Is a lockfile enough?
It helps a great deal, since it pins the exact version and hash that was approved. It does not protect the first install or the moment you update. Combine it with registry configuration and reserved names.
Related
Terms that sit next to this one
Typosquatting
Publishing a package with a near-identical name, hoping a developer installs it by mistake.
Lockfile
A file pinning exact dependency versions so builds are repeatable and checkable.
Private registry
An internal package store that keeps your private code off public indexes.
Supply chain attack
Reaching you through a library, a build tool or a vendor you trust.
Build pipeline compromise
An attacker altering your build system so every release carries their code.
Which registry does your build trust?
This one lives in your build, not your running app. What we can evidence is proof-backed findings in the app, and a gate in CI/CD that can stop a build when one appears. Ask us to run it on one of your applications.
Or start with a $199 pilot on one application: thirty days, success criteria agreed before day one, credited against the annual if you convert.