Learn Ruby on Rails Book

Secure Gems with Bundle Audit

Time to time people discover security vulnerabilities in published software. Rubysec maintains a plain-text database of such security vulnerabilities.

ruby-advisory-db maintains a database of vulnerable Ruby Gems.

If we want to know if our Ruby application is using any of the versions of Gems that is vulnerable then we should run a scan of our Gemfile.lock against this database. This is exactly what bundler-audit does. bundler-audit is a utility program which looks at application's Gemfile.lock and then looks at ruby-advisory-db to see if we are using vulnerable version of Gem or not.

Bundler has a command bundle audit to invoke bundler-audit to do this.

1bundle exec bundle-audit
2
3Name: rails-html-sanitizer
4Version: 1.3.0
5Advisory: CVE-2015-7580
6Criticality: Unknown
7URL: https://groups.google.com/forum/#!topic/rubyonrails-security/uh--W4TDwmI
8Title: Possible XSS vulnerability in rails-html-sanitizer
9Solution: upgrade to ~> 1.0.3
10
11Vulnerabilities found!

This scan was run on a project, and we can see that one vulnerability is found.

bundler downloads the Ruby Advisory DB to the local machine time to time. We should always be running the scan against the latest copy of the Ruby Advisory DB.

To update our local copy of the Ruby Advisory DB we should execute the following command.

1bundle audit update
2
3Updating ruby-advisory-db ...
4Cloning into '/Users/raj.singh/.local/share/ruby-advisory-db'...
5remote: Enumerating objects: 10, done.
6remote: Counting objects: 100% (10/10), done.
7remote: Compressing objects: 100% (6/6), done.
8remote: Total 4863 (delta 4), reused 10 (delta 4), pack-reused 4853
9Receiving objects: 100% (4863/4863), 867.08 KiB | 3.82 MiB/s, done.
10Resolving deltas: 100% (2400/2400), done.
11Updated ruby-advisory-db
12ruby-advisory-db: 456 advisories

Note that bundle audit update does not do any audit. It only clones the ruby-advisory-db to the local machine so that next time when we do the audit is performed against this update copy.

Every time we want to do a scan we need to do two things.

  • Update the local Ruby Adisory DB
  • Run the audit

Both of these operations can be combined to a single command.

1bundle exec bundle-audit --update

Running Audit as part of CI

Who is going to this audit on a regular basis. The best answer is run this audit as part of CI.

bundle-audit --update is in our config file for Wheel.

Let's say that at 10 AM all our tests were passing. Then at 10:05 AM Ruby Advisory DB added a new vulnerability that was recently detected. Any test that runs after 10:05 AM will fail the audit check.

Here is what we see in the console for a recent run.

1#!/bin/bash
2bundle exec bundle-audit check --update --ignore=CVE-2015-9284
3Updating ruby-advisory-db ...
4
5Cloning into '/home/circleci/.local/share/ruby-advisory-db'...
6
7Warning: Permanently added the RSA host key for IP address '140.82.113.4' to the list of known hosts.
8remote: Enumerating objects: 10, done.
9
10remote: Counting objects: 100% (10/10), done.
11
12remote: Compressing objects: 100% (6/6), done.
13
14remote: Total 4863 (delta 4), reused 10 (delta 4), pack-reused 4853
15
16Receiving objects: 100% (4863/4863), 865.47 KiB | 21.11 MiB/s, done.
17
18Resolving deltas: 100% (2400/2400), done.
19
20Updated ruby-advisory-db
21
22ruby-advisory-db: 456 advisories
23
24Name: actionpack
25
26Version: 6.0.3.1
27
28Advisory: CVE-2020-8185
29
30Criticality: Unknown
31
32URL: https://groups.google.com/g/rubyonrails-security/c/pAe9EV8gbM0
33
34Title: Untrusted users able to run pending migrations in production
35
36Solution: upgrade to >= 6.0.3.2
37
38
39
40Name: rack
41
42Version: 2.2.2
43
44Advisory: CVE-2020-8184
45
46Criticality: Unknown
47
48URL: https://groups.google.com/g/rubyonrails-security/c/OWtmozPH9Ak
49
50Title: Percent-encoded cookies can be used to overwrite existing prefixed cookie names
51
52Solution: upgrade to ~> 2.1.4, >= 2.2.3
53
54
55
56Vulnerabilities found!
57
58
59Exited with code exit status 1
60CircleCI received exit code 1

In this case two gems actionpack and rack are found to be vulnerable. The solution is also printed in the log.

1Solution: upgrade to >= 6.0.3.2
2Solution: upgrade to ~> 2.1.4, >= 2.2.3

Upgrade the Gems to fix the error.