This article was originally appeared on TechBeacon.com on April 26, 2021. You can access it here.
The software supply chain has gotten more attention than usual in the past months, as companies have disclosed issues resulting from flawed approaches to protecting the integrity of their software-based applications. The software supply chain is weakly held together, and most people have no idea just how fragile it is. This state of things suggests we should be asking ourselves, "Can I vouch for all the software dependencies that make up my Ruby on Rails application?"
Before analyzing all of your applications, it's vital to understand the three main categories of software supply chain attacks: infiltrated repository, primed repository, and source swap. Any of these can result in the compromise of the third-party or open-source software you utilize in your applications.
Infiltrated repository attack
Infiltrated repositories are particularly devious because they involve the attacker using a social engineering attack to take advantage of a project owner's trust. An overwhelmed gem author may not have the time or resources to keep a package updated. Then a wolf in sheep's clothing comes along and offers to donate time to maintain the project. The well-meaning project owners provide the attacker access to the repository, allowing injection into the gem of whatever malicious code the attacker wants.
An alternative scenario involves the attacker directly targeting weak credential management within a repository. Sensitive data should never be stored in repositories where everyone can see them. An attacker may take the time to scrape your repository for keywords to use in a dictionary attack, gaining commit authority. Attackers are persistent and creative, and once they have credentials, they will publish an updated version of the package, including their malicious code. They will take advantage of the trust relationships you have built in the community to cause the download of this now malicious package.
Primed repository attack
It takes a patient attacker, and often a lazy developer, to execute a primed repository attack. A primed repository is when a convenience package exists for the sole purpose of being sneaked into codebases. An example is the "is_odd" gem. This gem returns "true" if the number evaluated is odd, and returns "false" if it is even. If you look at the source code, this gem doesn't even do the calculations itself! It calls another gem called "is-int-even" and uses the "IsEven" method to check the number and return the opposite result.
Neither of these gems contains malicious code currently. This attack takes advantage of developers who are overusing third-party software to reduce development time and not truly measuring the usefulness of the packages they add. After you add the gem to your project, the attacker can modify the code in the "is-int-even" gem, and the next time you update your dependencies, it will now include the attackers' malicious code. These gems were created for instructional purposes only and will not have any malicious code in them ever. However, if you find them in your code, you should take a moment to reflect on your processes for how you choose which dependencies you include in your projects.
Source swap attack
The final and most common software supply chain attack is a source swap. In this approach, the attacker attempts to trick a developer into including a malicious package that appears to be legitimate. The most common source swap attacks use typosquatting. An attacker creates a project with a name similar to a popular gem, hoping that the developer makes a spelling or typing error and downloads the malicious gem instead.
Taking advantage of typing errors is not a new concept for nefarious actors. For years, attackers have used similarly named domain addresses to steal sensitive data from unsuspecting users. This type of attack against the software supply chain has seen a steady rise in recent years because of its effectiveness and because it requires minimal effort to deploy. Ruby developers' advantage is that RubyGems has built-in protection that prevents publishing new gems with similar names.
How to mitigate supply chain attacks in Ruby
Mitigating the risk of software supply chain attacks is a challenging task. In modern software development, it is impossible to remove dependence on third-party or open-source software. However, there are several steps you can take to reduce your risk.
Some things are out of the development team's control. You cannot force everyone who creates a gem to ensure they have MFA set up on their repositories. You also have no control over the vetting process on who works on those projects. You can make sound decisions to reduce your attack surface and manage the dependencies you choose to include in your code.
As a Ruby developer, embrace these three tips for securing your software supply chain: vet and curate your gems, audit your gems, and use software composition analysis (SCA) tools to integrate security checks into your pipeline.
1. Vet and curate gems
When vetting the gems to include in your Ruby project, you need to ask yourself a few questions. The first is, Do you really need the gem, or can you quickly write the added functionality yourself? If you decide the gem is necessary, ensure that the package is well documented and contains good codebase comments. The second question you should ask is about gem maintenance: When was the last commit? An under-maintained and poorly documented gem should raise some red flags. Stale packages are ripe for attackers to target for malicious purposes.
Even after the vetting process and deciding to include a gem in your project, you cannot assume it will always be good and forget about it. You must continuously audit your gems because of newly found vulnerabilities. The ruby-advisory-db maintains a database of vulnerable Ruby gems. The bundler-audit utility looks at the application's gemfile.lock and the ruby-advisory-db to see if you are using a vulnerable version of a gem. You should integrate this into your CI pipeline to automate the task instead of running it manually.
2. Audit your gems
Your applications change over time. You constantly add and remove code. You make revisions and refactor code for security or performant reasons. When this happens, you end up with stagnant gems in your projects that are no longer needed. It takes an exceptionally long time to go through all packages to remove the useless ones manually. You can run the command "bundle clean --force" to remove any unused libraries from a project. Don't let stagnant gems stick around. They become a target for would-be attackers.
3. Use SCA tools to integrate security into the pipeline
Include SCA tools to check for vulnerabilities and break the build if you have a known vulnerability. These tools must integrate into your CI pipeline. Two top-rated tools to conduct SCA for Ruby applications are Synk and Sonatype's Chelsea. Synk and Chelsea will check for vulnerabilities in your third-party packages. Automate security whenever possible. These scans should be a step in your CI pipeline that runs every time you push code.
All eyes on the software supply chain
There are benefits to using third-party gems in your Ruby on Rails projects. However, knowing that attackers will target your applications using techniques such as an infiltrated repository, primed repository, and source swap, you must be vigilant to include only helpful, safe, and needed gems in your projects. Vet and curate those gems, audit them, and use SCA to prevent attackers from taking advantage of your software supply chain and infiltrating your projects.