Open Source Code, Basically
The world of modern software is built like a house of cards.
Software development in the modern age is heavily reliant on open source libraries and tooling. Open source code projects are often built upon layers of dependencies – a broad engineering term for the libraries or collections of code that a larger project reuses. Oftentimes, libraries that literal millions of projects use as a dependency have just one maintainer (just one person behind it), and those libraries will often have their own dependencies.
These open source libraries are foundational, but they are not robust.
So sometimes, it only takes one little touch to bring the whole house down.
It’s safe to assume that all developers are using dependencies in their projects, and those dependencies are the most vulnerable part of this giant house of cards. If a critical dependency goes down, entire software products could stop working, leading to unexpected downtime and losses of revenue.
JavaScript’s NPM is a Typical Example
Open source dependencies are distributed with package managers , tools that allow developers to download, install, and manage libraries to incorporate them into their projects.
Javascript’s Node Package Manager (NPM) is a typical example. It’s worth examining because:
It has had serious dependency-related incidents before. Javascript is the most popular programming language as of 2022, so NPM is widely used.
The left-pad Incident
The classic example of open-source dependencies gone wrong is 2016’s left-pad incident.
Left-pad is 11-lines of JavaScript code that is used to add characters to the beginning of a string of text. It’s a necessary function that most devs could write themselves, but use left-pad instead to save time. Left-pad received about 2.5 million downloads per week.
Left-pad was maintained by just one-person, a 20-something year old who had 273 projects in NPM. The maintainer got very upset at NPM’s treatment of his projects, so he pulled them all down, including left-pad. This was the first card to fall that brought the house down.
React , the most popular JS web framework at the time, used left-pad as a dependency. When left-pad got removed, React stopped working. And every single project that used React as a dependency got hit with this error when they tried to run their code:
npm ERR! 404 'left-pad' is not in the npm registry.
The most popular framework of the most popular programming language was temporarily taken down by a single unhappy maintainer. This in-turn took down a huge number of projects that relied upon these dependencies. Needless to say, this affected an enormous swathe of the tech industry.
NPM Dependency Confusion Attack
Unfortunately, rogue maintainers aren’t the only thing to worry about.
An exploit known as a dependency confusion attack is emerging. In this attack, the bad guys name a malicious package very similarly to a legitimate package to get people to accidentally list the bad package as a dependency. If left-pad gets 2.5 million downloads per day, how many downloads might a malicious leftpad or left_pad get?
This is similar to typosquatting, in which an attacker creates a fake website named similarly to a target, hoping that a user will misspell the website name and go to the malicious site..
A proof-of-concept attack using this method happened recently in Germany, giving the NPM world another scare.
Researchers discovered that a German media conglomerate accidentally exposed its list of dependencies used in a private code repository, which allowed the attacker to target specific packages in that repository with a typosquatting attack. For a few days, the Internet had no idea who orchestrated this attack, until a cyber research firm admitted to it in a Twitter post . Thankfully, this turned out to be a red-team exercise and not a malicious attack.
Fake modules can be given even more legitimacy in some package managers by associating with trusted parties. A bug in NPM in late April of this year allowed attackers to add anyone to be an official maintainer of their module, without their permission. While this bug is now fixed, there was a fair window of opportunity for an attacker to make a very convincing malicious package with this technique.
NPM Domain Takeover attack
Now, instead of looking at the past examples of NPM issues, it’s time to look forward. The latest and greatest in package manager exploits is a domain takeover attack .
Earlier this year, another huge scare in the NPM world came when security researchers identified that nearly 3,000 project maintainers were using expired domains to host the email addresses they used on NPM.
These expired domains were being openly sold on sites like GoDaddy, which meant that an attacker could purchase that domain, take over the associated email account of a maintainer, and update any module they maintained with whatever code they wanted.
One researcher actually implemented this takeover attack on the ‘foreach’ package to preempt any bad actors from doing the same. This simple module had 36,825 projects dependent on it at that time, and averaged 6 million downloads per week. The researcher joked that this exploit could “achieve world domination.”
What are the defenders doing?
After reading all that, you might think, “what’s preventing an attacker from waiting until a very widespread module’s maintainer’s domain expires, and putting whatever malicious code they want into it?”
And that’s a very good question to ask. As of right now, it’s up to the diligence of NPM and security researchers to try and warn people before it happens.
Is there anything I can do to protect myself?
As scary as the above can be, there’s lots you can do to prevent these exploits from impacting your business!
While the core of this issue is out of your hands, there are a number of actions you can take to reduce the impact these exploits can have on your business. Here is a small list:
Create and maintain a list of open source libraries. Monitor your packages with GitHub’s dependency review enforcement and tools like Snyk , SonarQube , Black Duck , Veracode , Mend , or even the humble Dependabot . Require all libraries added by devs to be approved in code reviews. Consider rejecting them if any of the following apply:There is only one maintainer. There have been no updates in the last year. The domain of the maintainer is vulnerable to takeover. Code from the library interacts with sensitive parts of your own proprietary code.
Other Technical Mitigations
There are a number of other technical mitigations you can try to use to combat this issue. Snyk compiled a list in an article on their blog .
NPM is Not Alone
NPM is not the only open source package manager at risk.
This is a structural issue in the software development world and its reliance on open-source code. Open-source supply-chain attacks are one of the largest areas for widespread exploits in all of the infosec sphere. It would be wise to put this issue on your radar and try to get ahead of it.
A house of cards has a weak foundation, so don’t let one serve as an uninspected part of your software!
Want to get great cybersecurity content delivered to your inbox? Click here to sign up for our monthly newsletter, Tales from the Click.