Why Your Build Chain Might Be Installing Random Packages
If you’re a business leader and your project accidently includes malware in its code, this could endanger your reputation, customer security, and future sales. Many modern software development projects use libraries and packages hosted in public code repositories, such as GitHub, PiP, npm, or Gradle. While all of these tools have some security measures to ensure common packages are free from malicious inclusions, there is still the risk of a software supply chain attack.
Many organizations take a hybrid approach to package distribution with internal packages as well as mirrors of those that are publicly available being hosted in private, internal repositories. This can be an effective mitigation against some supply chain attacks, but not all. The ease with which packages can be installed from public repositories — even when private repositories are hosting — is a double-edged sword. These supply chain attack vectors are more common than one might imagine and have been shown to work in the real world.
A recent write-up by Alex Birsan, a fulltime hacker specializing in software development and bug bounty hunting, demonstrated these attacks. He easily took advantage of public/private name conflicts, which he called “dependency confusion.” He accomplished this by registering unused public package names on popular public repositories that match the names of private packages hosted internally on target organization’s infrastructure.
This is a manifestation of CWE-427: Uncontrolled Search Path Element.
Here’s how it worked. First, Birsan pulled the names of internally hosted packages at several organizations including Paypal, Tesla, and Apple as referenced in public-facing web resources. Next, he registered, and after uploading a package with a newer version number, software build chains at these companies pulled in his packages and called out to a custom authoritative name server he set up to log who was vulnerable to this attack. Interestingly, even if the build process failed at the target organizations, his custom package would often still run.
For additional information on the execution of these types of attacks, refer to:
• CAPEC-159: Redirect Access to Libraries, as creating a library in the search space that overrides the developers intent is the attack, and;
• CAPEC-176: Configuration/Environment Manipulation, as the change of an external files or settings to an application (the system that builds the software) to override the developer’s intent is the attack.
Fortunately, this is an attack path with known mitigations. Hosting local, vetted copies (through code analysis) of public packages on an internal repository and configuring build chains to pull only from that repository can prevent the inclusion of potentially nefarious publicly hosted dependencies. Additionally, some package managers support the area where you can pull code from (scope limitations). By specifying a limited scope, organizations can ensure their developers are not inadvertently pulling in incorrect or malicious versions of private packages. For more information, read this paper by Microsoft to support your mitigation strategies.
Make sure that you are pulling in the intended dependencies when building code. If you don’t mitigate these weaknesses and attacks, you can’t claim that you have a proper secure software development lifecycle. This weak software development lifecycle can cost you reputationally and financially.