Bug hunter rewarded with $130k payout for ‘dependency confusion’ vulnerability
A security researcher has detailed how he was able to hack into systems belonging to Apple, Microsoft, PayPal, and other major tech companies in a novel software supply chain attack.
Bug hunter Alex Birsan detailed in a blog post published yesterday (February 9) how he gained access to his targets’ internal systems by exploiting a vulnerability dubbed ‘dependency confusion’.
Dependency confusion is the name given to a vulnerability that can allow an attacker to execute malware within a company’s networks by overriding privately-used dependency packages with malicious, public packages of the same name.
Many companies use both private and public dependencies in their source code. Public dependencies can be uploaded to open source depositor GitHub by anyone, meaning that they could potentially contain malicious code.
What’s in a name?
Birsan said he came up with the idea for dependency confusion when studying a Node.js file meant for internal PayPal use, which was shared by his researcher friend Justin Gardner.
The code contained both private and public dependencies, said Birsan. Under further inspection, he realised that some of the private package names did not exist on the public NPM registry.
“What happens if malicious code is uploaded to NPM under these names?” Birsan wrote.
“Is it possible that some of PayPal’s internal projects will start defaulting to the new public packages instead of the private ones?”
Birsan tested his theory, uploading malicious code to public NPM dependency registries under the names of private packages he found on GitHub, package hosting sites, and online forums. None of these private packages were already listed as public.
The researcher found that if a dependency package was listed under the same name on both public and private repositories, the public version would be given priority and would be used instead.
Worryingly, the attack did not need any interaction from the developer to be successful, automatically replacing private packages with Birsan’s malicious public one.
“Thankfully, NPM allows arbitrary code to be executed automatically upon package installation, allowing me to easily create a Node package that collects some basic information about each machine it is installed on through its preinstall script,” Birsan said.
He then sent the information back to himself using DNS exfiltration in order to evade detection by developers.
The researcher later carried out the same technique by creating public RubyGems and Python packages, porting his malicious code into the dependencies and recreating the attack.
Birsan was able to exploit this vulnerability to breach the internal systems of the above mentioned organisations as well as Shopify, Netflix, Yelp, Tesla, and Uber – earning at least a $130,000 bug bounty in the process.
The vulnerability was detected inside more than 35 organizations across all three tested programming languages, he wrote, adding that the “vast majority of the affected companies fall into the 1000+ employees category, which most likely reflects the higher prevalence of internal library usage within larger organizations”.
From one-off mistakes made by developers on their own machines, to misconfigured internal or cloud-based build servers, to systemically vulnerable development pipelines, one thing was clear: squatting valid internal package names was a nearly sure-fire method to get into the networks of some of the biggest tech companies out there, gaining remote code execution, and possibly allowing attackers to add backdoors during builds.
Protecting against the attack
The issue has since been confirmed to have been fixed by Apple, Yelp, and Microsoft, the latter of which has released an in-depth advisory (PDF) on how to mitigate risk when using private packages.
Microsoft, which awarded its highest bug bounty payout of $40,000 for the vulnerability, told users to ensure all private packages are unavailable on public feeds, or make sure they are accessed through a single feed that safely merges public and private views.
More information on how to safely use private dependency packages can be found in the advisory (PDF).