Cybersecurity In-Depth: Feature articles on security strategy, latest trends, and people to know.

Bad actors practice to deceive package managers with a tangled web of methods. Here's how to hoist them by their own petard.

Liad Cohen, Security Researcher & Developer, OX Security

September 8, 2023

5 Min Read
A roast turkey dinner with a garnish of a rose made out of beet slices
Source: Vitolef via Alamy Stock Photo

"What's in a name? That which we call a rose By any other name would smell as sweet." When Shakespeare wrote these words (Romeo and Juliet, Act 2, Scene 2) in 1596, he was saying that a name is just a convention. It has no intrinsic meaning. Juliet loves Romeo for who he is, not for his name.

But without knowing it, Shakespeare was also describing dependency confusion attacks.

Dependency confusion is when packages you are using in your code are not yours. They have the same name, but it is not your code that is running in production. Same name, but one package smells like a rose and the other ... stinks.

Recent research reports estimate that 41% to 49% of organizations are at risk for dependency confusion attacks. New research from OX Security shows that when an organization is at risk for a dependency confusion attack, 73% of its assets are vulnerable. The research focused on midsize and large organizations (1K+, 8K+, 80K+ employees) across a wide range of sectors — finance, gaming, technology, and media — and found the risk in every sector across organizations of all sizes. The research also found that almost all applications with more than 1 billion users are using dependencies that are vulnerable to dependency confusion.

This article aims to help you understand dependency confusion and how to prevent it.

Double, Double

Dependencies (also called packages) are the building blocks of your software. Typically these pieces of software, whether developed by entire communities or within a company, perform a common and necessary task.

Package managers are frequently used to install dependencies and keep them updated. They scan public and private registries for the name of the package and, all other things being equal, select the highest version number. Attackers take advantage of this by placing a "dummy" package on the public registry with the same name but higher version.

When a package manager comes across two identical packages, one in a public registry and one in a private registry, it causes confusion — hence the name "dependency confusion." Since the two packages are identical, the manager will automatically choose to install the one with a higher version — in this case, the attacker's malicious package.

This gives hijackers a back door into your software. From this point, they can execute data breaches, perform intellectual property theft, and otherwise compromise the software supply chain of trust. They can also introduce compliance violations that will trigger severe regulatory penalties.

Toil and Trouble

There are various approaches to a dependency confusion attack.

  • Namespacing. By uploading a malicious software library to a public registry — such as the Python Package Index (PyPI) or JavaScript's npm registry — that is named similarly to a trusted, internally used library, systems that omit a namespace/URL check or do not force fetching from a private registry may mistakenly pull in the malicious code. The recent PyTorch dependency confusion incident is one such example.

  • DNS spoofing. By using a technique like DNS spoofing, systems can be directed to pull dependencies from malicious repositories while displaying what looks like legitimate internal URLs/paths.

  • Scripting. By modifying build/install scripts or continuous integration/continuous delivery (CI/CD) pipeline configurations, systems can be tricked into downloading software dependencies from a malicious source rather than a local repository.

Things Done Well and With a Care

To protect against dependency confusion, institute these practices.

  • Set policies in the package manager. Disallow package managers from prioritizing a public package over a private package.

  • Always include an .npmrc file. If you're using the popular NPM as a package manager, always include an .npmrc file that specifies where to fetch packages under specific organization scope.

  • Reserve package name in a public registry. Another way to protect against dependency confusion attacks is to reserve the package name in a public registry so that hijackers cannot use it and, therefore, cannot "trick" the package manager into installing a malicious package.

To fully protect against dependency confusion attacks, organizations should always use organization scopes for all internal packages, even when publishing to your internal registry. Organization scopes should also be registered at NPM's public registry, thus preventing anyone from hijacking the scope and taking advantage of the confusion.

Package names should also be registered publicly. If an organization is using the popular PIP as a package manager for Python dependencies, for example, it should create internal packages with a strict suffix that is recognizable and will work across all projects. Upload an empty package with the same name to the public registry PyPI as a placeholder.

Another reason to reserve the package name in a public registry is because if someone else reserves it (maliciously or not), developers will have to change all package names in the private registry to one that has yet to be reserved on the public registry. This can be a long and tedious process.

It is important to note that not all package registries allow users to reserve package names, so make sure you find one that does.

Exit, Pursued by a Bear

Dependency confusion attacks pose a serious and imminent cybersecurity threat to organizations globally. About half of all organizations are at risk, and 73% of those organizations' assets are exposed. To counter this growing threat, organizations must implement robust preventive measures and adopt cybersecurity best practices.

Shakespeare's roses may have presaged the risk of dependency confusion attacks by hundreds of years, but another quote from the Bard may hold some wisdom for protecting against them: "Let every eye negotiate for itself and trust no agent." (Much Ado About Nothing, Act 2, Scene 1)

About the Author(s)

Liad Cohen

Security Researcher & Developer, OX Security

Liad Cohen is a security researcher and developer at OX Security, where he engages in R&D of next-generation end-to-end software supply chain security and DevSecOps. He earned a BS in computer science and mathematics and an MS in computer science and applied mathematics from Ariel University. In 2018, he placed 5th in Israel, 33rd worldwide, in the International Internet Mathematical Olympiad.

Keep up with the latest cybersecurity threats, newly discovered vulnerabilities, data breach information, and emerging trends. Delivered daily or weekly right to your email inbox.

You May Also Like

More Insights