Run bundle-audit from rake

January 03, 2015

Reading time ~3 minutes

bundle-audit is a command-line utility provided by the bundler-audit ruby gem. It does patch-level vulnerability scans on your Ruby dependencies by working with bundler to inspect your project's Gemfile.lock.

I want to run bundle-audit from a rake task in a Rails project. Here's how I did it.

This is my lib/tasks/bundle_audit.rake file.

 1require 'bundler/audit/cli'
 2
 3namespace :bundle_audit do
 4  desc 'Update bundle-audit database'
 5  task :update do
 6    Bundler::Audit::CLI.new.update
 7  end
 8
 9  desc 'Check gems for vulns using bundle-audit'
10  task :check do
11    Bundler::Audit::CLI.new.check
12  end
13
14  desc 'Update vulns database and check gems using bundle-audit'
15  task :run do
16    Rake::Task['bundle_audit:update'].invoke
17    Rake::Task['bundle_audit:check'].invoke
18  end
19end
20
21task :bundle_audit do
22  Rake::Task['bundle_audit:run'].invoke
23end

It defines a few rasks under the bundle_audit namespace. Thanks to the modular Ruby code built on top of thor I had no trouble tapping directly into the command-line implementation for bundle-audit.

1$ rake -T bundle_audit
2rake bundle_audit:check   # Check gems for vulns using bundle-audit
3rake bundle_audit:run     # Update vulns database and check gems using bundle-audit
4rake bundle_audit:update  # Update bundle-audit database

Invocation is as easy as you can imagine. On the command-line:

1$ rake bundle_audit:run
2Updating ruby-advisory-db ...
3From https://github.com/rubysec/ruby-advisory-db
4 * branch            master     -> FETCH_HEAD
5Already up-to-date.
6ruby-advisory-db: 108 advisories
7No unpatched versions found

As you can see this does two things. First, it updates your local copy of the ruby-advisory-db. Then it scans your gem dependency graph looking for unpatched dependencies. What you see above is the output when everything is OK.

I also incorporated the check into my rake test task, because I want my tests to fail if I'm shipping with vulnerable dependencies. Here's what I have going on in lib/tasks/test.rake:

 1# Remove the Rails defaults.
 2Rake::Task['test:all'].clear
 3Rake::Task['test:all:db'].clear
 4Rake::Task['test:db'].clear
 5Rake::Task['test'].clear
 6
 7namespace :test do
 8  desc 'Run all tests'
 9  task all: :environment do
10    Rake::Task['bundle_audit'].invoke
11    Rake::Task['brakeman:run'].invoke
12    Rake::Task['rubocop'].invoke
13    Rake::Task['spec'].invoke
14  end
15end
16
17task :test do
18  Rake::Task['test:all'].invoke
19end
20
21# Running `rake` should run all my tests.
22task default: :test

Since this is part of my testing expectations I can also rest easy because my continuous integration tool has my back on every change, too.

Speaking at Your Event

My speaking schedule is getting complicated this year so I made a page to keep track.… Continue reading

Redefining Culture Fit

Published on November 06, 2015

The cloud-native future

Published on September 02, 2015