Dependency Confusion: What It Is, How It Works, and How to Fix It


Typosquatting package managers is a familiar and well-documented security issue that targets developers who misspell dependencies. However, recent research has demonstrated a similar yet much more prevalent user security misconfiguration in several popular package managers, dubbed dependency confusion.
A team of researchers disclosed this vulnerability and managed to exploit several global companies, including Paypal, Microsoft, Apple, Netflix, Shopify, Yelp and Uber. They received bug bounty payouts totalling over $130,000.
What is dependency confusion?
Dependency confusion is a supply chain attack threat that exploits how certain package managers resolve package names. When a build system is configured to use both private (internal) and public repositories, an attacker can upload a malicious package to the public registry using the same name as a private internal package — but with a higher version number. The package manager then downloads the attacker's public package instead of the legitimate private one, silently compromising the build.
The technique was first disclosed in February 2021 by security researcher Alex Birsan, who documented how squatting valid internal package names proved a near-certain method for gaining access to the networks of some of the world's largest technology companies.
The vulnerability
When a mix of local and remote packages are included in a build, some package managers will attempt to download each package from the public remote server before checking local repositories. Any packages that are expected to be local-only could be overridden by uploading a package of the same name to the remote repository. This will largely affect packages that are built by organizations and not publicly available.
The following package managers are known to be affected:
- NPM
- RubyGems
- PyPi
- JFrog
- NuGet
Example: vulnerable Python configuration
The example below shows a typical requirements.txt that can be used to pull Python packages from the PyPi repository.
defusedxml
bandit
beautifulsoup4
flask
flask-auth-company-name
A vulnerable Python requirements.txt file
This configuration is vulnerable to a dependency confusion attack because the flask-auth-company-name is a local-only dependency that is not expected to exist in the remote repository.
The exploit
The exploit itself is easy to perform but there are several obstacles that need to be overcome. Firstly, an attacker must identify or exact the name of a package in use by the target company. Realistically, an attacker also needs to obtain the package – or even better, its source code. This allows them to create a malicious package that doesn’t cause immediate suspicion from builds or software failure.
An attacker can then upload the malicious package using the obtained name, ensuring it has a higher version number than that of the local package. The next time the build process is called, the malicious package gets downloaded from the repository and used instead of the local package.
These malicious packages are capable of infecting any build system or server they are installed on. This is an example of a supply chain compromise, similar to that seen in the SolarWinds attacks.
Mitigation
If your organization uses internally developed packages and any of the affected package managers, you need to mitigate this attack.
Most mitigations depend on which package manager is used. Microsoft has published a comprehensive whitepaper which details steps that can be taken to mitigate dependency confusion. The main points are:
- Avoid a hybrid approach and use only a single private repository. This can still pull in packages from a public repository but provides you with complete control of which packages it pulls.
- If supported by the package manager, always specify scopes to define where packages should be pulled from (currently only for NPM and NuGet).
- Use client-side validations, such as version pinning and integrity verification.
In short: eliminate hybrid resolution, use scoped package names where possible, and enforce version pinning. These three controls address the root cause of dependency confusion at the build pipeline level.
Try it yourself
If you have an Immersive licence, you can try your hand at performing a dependency confusion attack against a build server in our latest infrastructure hacking lab. In this lab, you’ll analyse and compromise a target build server by writing and uploading a malicious Python package. Log in here.
If you don't have a licence for Immersive, why not book a demo to get a guided tour of our platform?
Frequently Asked Questions: Dependency Confusion
What is the difference between dependency confusion and typosquatting?
Typosquatting relies on a developer mistyping a package name. Dependency confusion requires no user error — the package manager itself is tricked into fetching a malicious public package over a legitimate private one, based solely on version number priority.
Which package managers are affected by dependency confusion?
NPM, PyPi, RubyGems, NuGet, and JFrog Artifactory have all been identified as potentially vulnerable, depending on how they are configured.
Has dependency confusion been used in real attacks?
Yes. Security researcher Alex Birsan demonstrated the technique against major companies including Apple, Microsoft, PayPal, Netflix, Shopify, Uber, and Yelp, earning over $130,000 in bug bounties. The same class of vulnerability has been observed in broader supply chain attacks.
How do I know if my organization is vulnerable?
If your build pipelines use a mix of internal and public package repositories, and your package manager resolves conflicts by version number rather than source priority, you are likely exposed. Audit your requirements files and CI/CD pipeline configurations to identify privately named packages that could be registered publicly by an attacker.

See how to prove readiness with one platform.
See how Immersive One helps technical teams and leaders prove readiness, close capability gaps, benchmark progress, and report cyber resilience with confidence.
