Often the most brilliant ideas are the most simple. The hard part is being the first one to come up with the idea and put it to use.
One such brilliant yet simple idea belongs to Alex Birsan, a researcher who came up with a method to breach 35 big tech companies including Microsoft, Apple, Yelp, Paypal, Shopify, Netflix, Tesla, and Uber, that’s earned him $130,000 in bug bounties.
Dependency confusion
This method relies on so-called “dependency confusion.” Basically, it exploits the confusion about the possible locations that computer programs (in this case popular package managers like npm, PyPI and RubyGems) use to find the files a project depends on.
All of these package managers will accept dependencies listed as names and try to resolve what the developer meant. They will look for dependencies locally, on the computer where a project resides, and they will check the package manager’s public, Internet-accessible, directory.
Birsan found that the affected companies used locally stored files that were not present in the open-source directory.
The example below shows an abbreviated package.json
file that lists the dependencies for a private project created by PayPal, that ended up on GitHub. Birsan noticed that while some dependencies, like
express
in this example, were present on the public npm repository, others, like pplogger
, were instead PayPal’s privately created npm packages, used and stored internally by the company. "dependencies": { "express": "^4.3.0", ... "pplogger": "^0.2", ... }
Birsan wondered if malware could be introduced to these projects by creating packages on the public npm repository that matched the names of these local dependencies.
To test his idea he started looking for effective places to upload his own “malicious” Node packages to the npm registry under all the unclaimed names. Because npm allows arbitrary code to be executed automatically when a package is installed, his code was able to “phone home” from each computer it was installed on and tell him when his idea had worked.
Making the call home
Getting the information to his own server from deep inside well-protected corporate networks posed yet another problem which was solved by using DNS exfiltration. DNS data exfiltration is a way to exchange data between two computers without any direct connection, in a way that doesn’t draw much attention.
During the exfiltration phase, the client makes a DNS resolution request to an external DNS server address. Instead of responding with an A record, the attacker’s name server will respond with a CNAME, MX or TXT record, which allows a large amount of unstructured data to be sent between attacker and victim.
Version confusion
Besides expanding his original idea to both the Python and Ruby package managers, PyPI (Python Package Index) and RubyGems respectively, Birsan also tested what would happen if he uploaded a package with a higher and therefor “newer” version number than the actual last version. In these cases, the higher version on a public repository would get preference over an older local version. This increased his success rate even more.
The rewards
So far, Alex Birsan has been granted $130,000 from bug bounty programs. That may seem like a lot of money but imagine what he could have made by selling this trick to the highest bidder. We all have the devastating results of successful supply-chain attacks in our short-, and long-term memory.
According to Sonatype’s 2020 State of the Software Supply Chain Report, supply-chain attacks targeting open-source software projects are a major issue for enterprises, since 90% of all applications contain open-source code and 11% of those have known vulnerabilities.
And, like Alex Birsan, we would like to stress that all the companies he breached had given their permission to have their security tested by running bug bounty programs or by express permission. In other words, “don’t try this from your own basement or you might get dragged into court by your hoodie”.
Fixes
Most of the breached companies have taken actions to prevent this type of attack, but the method is still usable. The underlying problem needs to be fixed for the entire ecosystem and not on a company by company basis, because we all know there will always be dawdlers that are too late. We note that package.json
files allow dependencies to be listed as full URLs, which may provide some resilience to this form of attack.
The most gratifying part of this method is that it does not rely on social engineering. If you can find the filenames, you can execute the plan.
For those that would like to read some more details, the whole story in Alex’s own words can be found in his Medium article and the accompanying Twitter thread.