Three tools, three jobs: what bundler-audit checks

Free preview 3 min to read

This app's CI, .github/workflows/ci.yml, runs two jobs whose names both sound like "security". scan_ruby runs bin/brakeman --no-pager, and scan_js runs bin/importmap audit. They are two tools with two different targets. Brakeman reads this app's Ruby and ERB source, looking for vulnerability patterns it recognizes: a raw SQL string built from user input, a render call fed unsanitized data, mass assignment without strong parameters. bin/importmap audit reads the JavaScript packages pinned in config/importmap.rb and asks the npm registry's advisory endpoint about each version.

Neither one answers this question: is the exact version of rails, or pg, or any of the other 163 gems in this app's Gemfile.lock, one with a publicly known vulnerability? Brakeman does open Gemfile.lock, but only to learn the Rails version and a few gem versions. It uses them for a fixed set of checks written for specific Rails CVEs, plus end-of-life warnings, and it doesn't compare every locked gem against an advisory database. Nothing in this app's Gemfile, Gemfile.lock or CI does that today.

The tool built for that question

bundler-audit is an independently maintained Ruby gem (version 0.9.3, license GPL-3.0-or-later) with one job. It cross-references every gem and version locked in Gemfile.lock against ruby-advisory-db, a separate, community-maintained database of known Ruby gem vulnerabilities. gem install bundler-audit installs it. Adopting it changes none of this app's code, because it only reads Gemfile.lock.

This app has no trace of it. A grep across Gemfile and Gemfile.lock for bundler-audit, bundle-audit and bundle_audit returns nothing. Compare Brakeman, which this app has adopted. Here is the shared group :development, :test do ... end block in Gemfile, in full:

group :development, :test do
  # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
  gem "debug", platforms: %i[ mri windows ], require: "debug/prelude"

  # Static analysis for security vulnerabilities [https://brakemanscanner.org/]
  gem "brakeman", require: false

  # Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/]
  gem "rubocop-rails-omakase", require: false

  # Testing framework
  gem "rspec-rails"
  gem "factory_bot_rails"
  gem "shoulda-matchers"
end

Brakeman sits there with require: false, like the other CI-only tools around it, and scan_ruby runs it. bundler-audit has no equivalent line. This course doesn't add one. It teaches the tool the way a team would adopt it and points out the missing piece at each step.

What this course covers

Seven lessons, checked against bundler-audit 0.9.3's installed source and this app's Gemfile and CI config. Lesson 2 covers the CLI commands and what they require. Lesson 3 reads what a single vulnerability record (an Advisory) holds. Lesson 4 walks through the report format, field by field. Lesson 5 sketches a CI job that would add the check to this app's pipeline. Lesson 6 shows how bundler-audit, Brakeman and bin/importmap audit divide the work. Lesson 7 puts the numbers back together, with a challenge built from bundler-audit's classification logic.

Lesson 1 of 7 · free

Keep going with lesson 2

The bundle-audit CLI: commands, flags, and this app's toolchain

Covers the bundle-audit commands and flags, where advisory data comes from, and this app's toolchain requirements.

A free account also gives you the quizzes, your progress and notes, and the discussion.

Type to start searching...