Modern software development with Ruby relies heavily on public repositories of open source gems, which greatly simplify code reuse, foster innovation and result in faster release cycles. As a result, Independent Software Vendors (ISVs) have integrated public repositories like RubyGems and GitHub into their software development processes often without fully understanding the significant security risks posed by their software supply chain.
Our State of Supply Chain Security survey showed that more than one-third of ISVs implicitly trust public repositories. This means they trust not only the repository itself, even though RubyGems offers no guarantees as to the security and integrity of the gems they provide, but also all of the open source developers that create gems, as well. As a result, they may end up incorporating compromised gems into their software, which they then distribute downstream to their customers who become vulnerable to cyberattack.
These kinds of supply chain threats are assessed in the 2021 Sonatype security report. The report documents that attacks on the software supply chain have grown exponentially by up to 650% since the start of the pandemic, and are primarily aimed at exploiting weaknesses in public repositories.
Two of the most common public repository exploits are typsoquatting and dependency confusion. Both exploits are software supply chain attacks that target the lax security of public repositories in order to infiltrate organizations with the goal of stealing personal, financial, or business data:
None of the major public repositories are immune, including RubyGems, which has had a number of recent malware incidents, including:
- In 2020, researchers discovered more than 700 typosquatting packages in what has been called the RubyGems package repository attack. Persistent spyware that sought to steal bitcoin wallet addresses was found in one of these packages.
- In 2021, BlackRuby2 ransomware was discovered, based on the original BlackRuby malware, which combined ransomware with crypto-mining to produce a malicious gem with a dual vector of attack.
- ReversingLabs maintains a list of other known compromised gems that should also be checked.
Public software repositories like RubyGems are here to stay, but organizations need to understand how to utilize them in a secure manner. While there are a number of best practices that can help minimize supply chain security threats, they cannot be completely eradicated. This post introduces the kinds of threats, solutions and justifications any organization serious about security can utilize to build a business case around securing their Ruby software supply chain.
Security & Integrity Gaps in the Ruby Ecosystem
Public repositories like RubyGems work so well because their “openness” allows anyone to publish any code they want, which ISVs can then reuse with trivial effort thanks to the Ruby package manager. But this very openness is what makes the Ruby ecosystem so vulnerable to supply chain exploits. More commonly, gem vulnerabilities and datedness represent weak links in the supply chain that can result in serious threats if not resolved.
Hijacking & BrandJacking
Ruby developers that haven’t implemented MFA are susceptible to having their RubyGems account hijacked by bad actors that can then compromise their published gems. Additionally, because bad actors are not restricted as to the gems they can submit, they can (and do) upload gems with the names of packages that are popular in other ecosystems in an exploit known as brandjacking, hoping to target users new to Ruby.
Gem Vulnerabilities Go Unpatched
The popularity of open source code is a two-edged sword: on the one hand, it means vulnerabilities are discovered and updated quickly, but on the other hand it also means those vulnerabilities are widespread. Most organizations already have at least one automated system designed to track gem Common Vulnerabilities and Exposures (CVEs) in order to raise awareness of exploits quickly, but tend to lack an automated solution for patching CVEs in a timely manner.
For example, the Synopsys 2020 Open Source Security and Risk Analysis Report found that 49% of the codebases they audited that year contained at least one high-risk open source vulnerability.
Legacy Gems and the Lack of Updates
Gems are updated regularly to improve functionality and/or fix vulnerabilities & bugs. Unfortunately, the same cannot be said of Ruby application codebases, which are rarely updated unless a critical bug or vulnerability is encountered. Developers who forgo the time and resources required to maintain the gems in their codebase on a regular basis often end up spending far more time and resources to plug the security holes and performance/stability bugs when a crisis occurs.
Interdependence Breeds Exploitation
While a gem may not be compromised, it’s no guarantee that the dependencies it incorporates (i.e., transitive dependencies) haven’t been compromised. Dependency trees can be both wide and deep. As a result, a single compromised component can have devastating ripple effects throughout the Ruby ecosystem.
Securing the Ruby Software Supply Chain
The Ruby supply chain starts with the RubyGems public repository, but extends through the systems that build gems from source code and distribute them for use. Implementing a secure, end-to-end supply chain can be difficult due to its depth and breadth:
- Tech Stack – most organizations work with more open source languages than just Ruby, and therefore need to import their code from more than one public repository. Because there are no industry-wide standards in place today, each language and repository must be treated uniquely.
- Import Controls – there is a large set of best-practice security and integrity controls you could implement in order to scrutinize the gems you import. Implementing them all would significantly decrease risk at the cost of extensive time and resources.
- Build Controls – to minimize risk, many organizations import source code rather than prebuilt gems since RubyGems offers no guarantees as to the security and integrity of the prebuilt gems they provide. Building gems (especially those with linked C libraries) for all the operating systems your developers use requires expertise to ensure against compromise during the build process, as SolarWinds and Codecov found out to their detriment.
- Usage Controls – typically, built artifacts like gems are stored and distributed via some kind of binary or artifact repository. To ensure against tampering, these private repositories should (at a minimum) feature signed gems created by a secure build service, or else be imported as signed artifacts from a trusted vendor.
Without the proper controls in place, organizations can open themselves to attack at multiple points across the depth and breadth of their Ruby software supply chain.
Ruby Supply Chain Security Out of the Box
Like it or not, ISVs are now the frontline of security for their customers. Those organizations that are serious about security will want to put in place the processes and policies necessary to ensure:
- Existing software development processes and systems have not been compromised.
- The Ruby software supply chain their developers use is secure going forward.
But as software supply chain complexity increases, verifying the security and integrity of the software development lifecycle will require automated solutions for importing, building and working with gems.
The ActiveState Platform offers Ruby developers just such an automated, turnkey solution for securing their software supply chain that includes:
- Secure Import Process: our automated system regularly checks upstream Ruby gem repositories like RubyGems and GitHub. For any newly released or new version of a gem, it will:
- Download both the source code and associated metadata.
- Perform static analysis on the gem’s code to ensure our data about it is complete before inserting it into our catalog.
- Check popular vulnerability databases so we can augment our gem metadata with CVE information.
- Regularly monitor the source code we ingest, and remove it from the catalog/pipeline if it is found to contain a trojan, malware, etc.
- Secure Build Service: our automated build service runs in the cloud on a minimal set of predefined, locked down resources in order to minimize the attack surface. The service incorporates:
- Build scripts that cannot be accessed and modified within the build service, preventing exploits.
- Ephemeral, isolated build steps that execute in their own containers, which are discarded at the completion of each step. In other words, containers are purpose-built to perform a single function, reducing the potential for compromise.
- Hermetically sealed environments that have no internet access, preventing (for example) dynamic packages from including remote resources.
- Reproducible builds where the build process fails safe, terminating the build if any component generated during a build step fails its checksum verification.