April 22

1 comments

Use the Bundle Outdated command to keep your Rails applications secure

By Christopher G Mendla

April 22, 2019


Last Updated on September 9, 2023 by Christopher G Mendla

Using outdated gems in your Ruby on Rails application introduces vulnerabilities to your Rails Applications. There is an easy way to find outdated gems using the Bundle Outdated command.

Updating your Rails Applications

Do not go blindly along the updating path. Use version control and test the results of your updates. Be sure you have a solid backup and recovery plan in place.

Check your Rails version

The first thing to do is to check to see if you are on a current version of Ruby and Rails. The commands are ‘rails -v’ and ‘ruby -v’. Compare that with the latest releases of Ruby and Rails. Note that upgrades can be tricky so proceed with caution.

If you are significantly behind in your Ruby or Rails releases, you need to determine if you should update them first or update the outdated gems first. When updating Rails, you should update ALL of the code that changed between releases by checking railsdiff.org. Too many developers and teams just make the changes they think are critical which results in the underlying application code diverging from the true release code.

Check for outdated gems

The next step is to determine how many outdated gems you have. The basic command is ‘bundle outdated’. However, you can modify that with grep and a pipe to get a count:

$ bundle outdated | grep -c "*"

This will return the number of outdated gems. This pipes the bundle outdated command to grep. The -c says count and the “*” is a handy way to get a unique count due to the way the list is returned.

Not all gems can be updated due to dependencies.

If you are using a test suite and rubocop, now would be a good time to run the test suite. The next step is to run ‘bundle outdated’ to see the gems. You will get results similar to the following

 $ bundle outdated

Fetching gem metadata from https://rubygems.org/............
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies............

Outdated gems included in the bundle:
  * actioncable (newest 5.2.3, installed 5.0.2)
  * actionmailer (newest 5.2.3, installed 5.0.2)
  * actionpack (newest 5.2.3, installed 5.0.2)
  * actionview (newest 5.2.3, installed 5.0.2)
  * active_model_serializers (newest 0.10.9, installed 0.10.4) in groups "default"
  * activejob (newest 5.2.3, installed 5.0.2)
  * activemodel (newest 5.2.3, installed 5.0.2)
  * activerecord (newest 5.2.3, installed 5.0.2)
  * activesupport (newest 5.2.3, installed 5.0.2)
  * arel (newest 9.0.0, installed 7.1.4)
  * autoprefixer-rails (newest 9.5.1, installed 7.1.2.3) in groups "default"
  * bcrypt (newest 3.1.12, installed 3.1.11, requested ~> 3.1.7) in groups "default"
. . . 

Note that some of the gems show as being in a group and others do not. The gems that are shown as being in a group are gems that are listed in your gemfile explicitly. It is a good practice to call out the version in your gemfile

For example, here are three basic ways of calling a gem

gem samplegem              # no version is specified
gem samplegem, '1.1.1'     # locks that gem to version 1.1.1
gem samplegem, '~> 1.1.1'  # calls for version 1.1.1 but bundle update 
                           # will update to the highest minor version 

Run bundle update

You can try ‘bundle update’. This will attempt to update all the gems that are not explicitly called in the gemfile or can be updated to a version compatible with the ‘~>’ version specified.

Run your tests

Now, run your tests. Are they still passing? Test the app in development. Is it still running OK? If you are lucky, it will test and run OK. If not, you will need to do some research as to why it failed. You are working with version control and can reset the branch, right?

Alternative – Update each gem manually

Another alternative is to manually update each gem and then run your test suite. That can be time consuming and doesn’t always give predictable results. For example.

$ gem update samplegem
$ bundle install
$ rspec  # or whatever command launches your test suite. 

You will probably not be able to get all of the gems updated. If you want to see what other gems use a particular gem, you can do this

$ gem dependency -R thor
Gem thor-0.20.3
  bundler (~> 1.0, development)
  Used by
    rack-test-1.1.0 (thor (~> 0.19, development))
    railties-5.2.2.1 (thor (>= 0.19.0, < 2.0))

This shows which gems use the thor gem.

Once you get the gems that are not in the gemfile, you will need to look at the gems that are called out in your gemfile.

For example, if we see a line in the ‘bundle outdated’ results such as

  * puma (newest 3.12.1, installed 3.8.1, requested ~> 3.0) in groups "development, test"

We should be able to find that line in the ‘development, test’ group in our gemfile.

group :development, :test do
  gem 'byebug', platform: :mri
  gem 'pry-rails'
  # Use Puma as the dev app server
  gem 'puma', '~> 3.0'
end

To update to the latest current version of Puma (assuming there are no compatibility issues, you can change it as follows

group :development, :test do
  gem 'byebug', platform: :mri
  gem 'pry-rails'
  # Use Puma as the dev app server
  gem 'puma', '~> 3.12.1'
end

Bundle install and test

Then run ‘bundle install’ . Then run your test suite.

Summary

The process is tedious. In a production environment, you will probably be running bundle outdated several times a week. Constant integration apps such as Jenkins can be configured to fail builds that have over a set number of outdated gems.

You will occasionally run into situations where updating a gem causes conflicts that will break your app, build or tests.

Securing your rails application
Securing your rails application

Christopher G Mendla

About the author

A web developer living in Southampton, PA

Self motivated critical thinker and problem solver providing technology consulting services.

Leave a Reply

Your email address will not be published. Required fields are marked

  1. Pingback: Checking an Angular project for outdated packages - Chris Mendla Tech
{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}