Software Supply Chain Strategies to Parry Dependency Confusion Attacks
“What’s in a name? That which we call a rose
By any other name would smell as sweet.”
— Romeo and Juliet, Act 2, Scene 2
When Shakespeare wrote these words in 1596, he was saying that a name is just a convention. It has no intrinsic meaning. Juliet loves Romeo the person, not for his name.
But, without knowing it, he 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-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 their assets are vulnerable. The research focused on both 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 a 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 both public and private registries for the name of the package and, all other things being equal, selects 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 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
Read More HERE