Dependency confusion is a pesky software development problem, as malicious actors employ a variety of tricks to trick developers and integrators into incorporating malicious software components into their codebase. Instead of getting the desired functionality in the application, the developers wind up with an application that behaves differently than expected or one with a backdoor that can be exploited by unauthorized parties.
Earlier this year, security researcher Alex Birsan illustrated how easy it was to upload code components to public package managers and code repositories and trick developers into downloading them. Birsan was able to exfiltrate data from companies such as Tesla, Apple, and Microsoft as part of this research. A month later, PyPI, or the Python Package Index, removed 3,653 malicious packages – including an unauthorized version of CuPy, a library for Nvidia's parallel computing platform CUDA – utilizing the same attack method.
The exploit process for a dependency confusion attack (or package namesquatting attack) is fairly simple, as it begins with the malicious actor uploading to a public repository a code package with the same name as a private internal package. The actor could discover the name of these private packages by looking through configuration files in publicly available projects. If a developer updates all the dependencies for a project and pulls from both private and public repositories, the build process defaults to grabbing the malicious package from the public repository instead of the one from the private internal package. By the time the developer has figured out that the wrong package was pulled, the malicious code has already been executed in the code and compromised the project. And if the build was performed as part of an automated process, as would happen in an continuous integration/continuous delivery (CI/CD) environment, this particular substitution could go unnoticed for quite some time.
Detecting Dependency Confusion
Application security teams will most likely implement the Dependency Combobulator at the CI level, says Moshe Zioni, vice-president of security research at Apiiro. For example, if the team uses Jenkins for its CI process, the toolkit may be used as part of the build process. Another place to use the toolkit would be during code commits and push requests, in which every change in dependency imports will be sent to the Dependency Combobulator for inspection and decision-making.
“It can potentially be interconnected via a plugin but that's a more convoluted way that is not easily supported out of the box and will need some extra development work," Zioni says.
There are numerous other tools that act similarly to Dependency Combobulator. Snyk offers snync, an open source tool to detect potential instances of dependency confusion in the code repository. Sonatype offers developers a dependency/namespace confusion checker script on GitHub which checks if a project has artifacts with the same name between repositories, and to determine whether the developer has been impacted by a dependency confusion attack in the past. Sonatype’s Nexus Firewall can quarantine suspicious or malicious open source components before they even enter the organization’s repository. There are private registries (Verdaccio sets up a private npm registries) and dedicated package management systems (such as Cloudsmith) that organizations can use to avoid this kind of attack.
Minimizing the Risks
There are ways organizations can minimize this type of risk to the software supply chain. GitHub, which owns npm and manages the public npm registry, recommends the following to deal with dependency confusion: Using scopes for internal packages to be explicit where the packages live; placing an .npmrc file in the project’s root to explicitly set the intended registry; being careful when using proxies; and responding promptly when something fails during the build process.
Another thing organizations can do is to pre-emptively name squat their own private dependency names. By claiming the names used for private dependencies, including namespaces and scopes, on public repositories, the organization ensures that adversaries cannot use them for their own purposes.
“We were eager to respond by creating a toolkit that can mitigate similar threats and be flexible and extensible enough to combat future waves of dependency confusion attacks,” Zioni says. “Addressing this attack vector is essential for organizations to successfully secure their software supply chains.”