Last week, malicious code was slipped into Bootstrap for Sass, the free, open-source, very popular, and widely deployed front-end web framework.
The good news: the good guys stamped it into oblivion lickety-split.
According to the timeline provided by Snyk – a company that provides tools to find and fix known vulnerabilities in open source code – the malicious version of the package was published on the RubyGems repository for Ruby libraries on 26 March (but not on GitHub, where the library’s source code was being managed).
Malicious actors had rigged that bad package – version 3.2.0.3 – with a stealthy backdoor that would have allowed for remote code execution (RCE) in server-side Rails applications.
Later that same day, software developer Derek Barnes smelled a rat and opened a GitHub issue for what he thought was a suspicious snippet of code in the brand-new – what would turn out to be malicious – version 3.2.0.3 of bootstrap-sass
. Just an hour later, the malicious version was yanked from the RubyGems repository, and the two developers responsible for maintaining the code had updated their credentials.
As of Wednesday, it hadn’t yet been confirmed how the attacker(s) had managed to publish the malicious RubyGem package, but the assumption was that they had gotten hold of a set of credentials.
So that’s the good news: it was actually spotted and dealt with very quickly, so kudos to Derek Barnes for spotting the problem and for everybody else who jumped on the fix so quickly.
A smatter of downloads
As far as impact goes, it could have been very bad indeed. The Boostrap for Sass package had been downloaded about 28 million times from the RubyGems portal as of Friday, according to official RubyGems stats. Before it was yanked, the backdoored version on RubyGems had only been downloaded 1,477 times… though, as Snyk points out, that number will increase “significantly” when counting its use in applications.
The “heads-up!” news: While this incident was spotted early and cleaned up quickly, it’s actually just one chapter in a much bigger story about how a vulnerable supply chain could threaten an entire software landscape. The story is also about how bad people are looking to exploit the way that code is written, and how much trust people place in third-party code.
Modern apps and web projects tend to have a lot of dependencies. Typically, developers rely heavily on third-party code: either by including it in their projects directly, or by including it in the toolchain used to build that project.
Both types of third-party code are managed by package managers that download the code you need for your project (and whatever code that code needs, and whatever code that code needs, and so on…) from sundry code repositories like GitHub or, in this case, because the code was a Ruby Gem, from the RubyGems repository.
Break or infect a small but useful piece of third-party code in a repository somewhere, and your code could silently poison thousands of projects and millions of users.
Not the first poisoned repository
We’ve seen similar issues with other package manager/repository combos:
An update to the ubiquitous Node Package Manager (NPM) changed critical Linux filesystem permissions, causing it to interfere with the operating system… breaking, well, everything.
The PHP ecosystem (PHP is the number one programming language for server-side web development) dodged a bullet in 2018 when a trivially exploitable vulnerability was found in its Packagist service.
As Naked Security’s Paul Ducklin said back in February 2018,
If Packagist were to be hacked and a rotten apple uploaded in a well-chosen place, a truly enormous barrel would end up poisoned.
Then, in October 2018, Python software developers could have found themselves hemorrhaging bitcoins thanks to a wily typosquatting attack. The malicious code, named with a misspelling of an innocent and popular software library, was uploaded to the PyPI repository. It was one of 12 such attacks spotted on that platform, in that month.
What to do?
Bootstrap-Sass v3.2.0.4 was also released on Thursday, on both RubyGems and GitHub, to remove any backdoor residue.
Both the 3.2.0.2 and 3.2.0.3 versions have been removed, and the project maintainers say that users need to upgrade.
As far as anybody has been able to discern, version 3.2.0.2 wasn’t actually malicious and had been pulled by the malicious actors in order to force users to upgrade to 3.2.0.3, which they published next. The clean version, 3.2.0.4, published on Wednesday, is identical to 3.2.0.2, which should make it an easy upgrade to a safe version.