How can I ensure that Ruby uses an OpenSSL not vulnerable to Heartbleed? How can I ensure that Ruby uses an OpenSSL not vulnerable to Heartbleed? ruby ruby

How can I ensure that Ruby uses an OpenSSL not vulnerable to Heartbleed?


After asking some questions elsewhere, my current understanding is this:

  • OpenSSL is never compiled along with Ruby; Ruby is simply told, at compile time, where to look for OpenSSL.
  • ruby -r rbconfig -e 'puts RbConfig::CONFIG["configure_args"]' should tell you where Ruby will look for various executables, including OpenSSL
  • All that matters is that the copy of OpenSSL at that location is up-to-date; cd there and use ./openssl version to find out.
  • ruby -v -ropenssl -rfiddle -e 'puts Fiddle::Function.new(Fiddle.dlopen(nil)["SSLeay_version"], [Fiddle::TYPE_INT], Fiddle::TYPE_VOIDP).call(0)' should give the same answer as running openssl version directly because it actually asks the copy of OpenSSL that Ruby is using to report its version number
  • OpenSSL::OPENSSL_VERSION may be out-of-date; it reports the version it found when it was compiled.


It is possible to have multiple versions of OpenSSL installed on your system. These two tests tell you which version would be linked to your Ruby if you were to do a build, and also which version is actually linked in the Ruby you are currently using.

As an example, let's say you are still using Ruby 1.9.3, and installed/compiled it last year. It would have been linked against the version of OpenSSL you had installed at the time. In the meantime you updated your version of OpenSSL (using Homebrew, for example), in response to the Heartbleed problem.

If you ran the first test you would get back OpenSSL 1.0.1g, the current version linked that you just upgraded.

If you ran the second test, it would reveal that your copy of Ruby is probably still linked to the older, vulnerable copy of OpenSSL.

By way of example, I'll use output from my own system (Mac OSX 10.9):

Results on the system Ruby (2.0.0):

[~] $ ruby -v -ropenssl -rfiddle -e 'puts Fiddle::Function.new(Fiddle.dlopen(nil ["SSLeay_version"], [Fiddle::TYPE_INT], Fiddle::TYPE_VOIDP).call(0)'` ruby 2.0.0p247 (2013-06-27 revision 41674) [universal.x86_64-darwin13]/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/openssl/ssl.rb:10    1: warning: assigned but unused variable - idOpenSSL 0.9.8y 5 Feb 2013[~] $ ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION'OpenSSL 0.9.8y 5 Feb 2013

Results on Ruby 2.1.1p76 (managed by rbenv, but could be RVM or other):

[~] $ ruby -v -ropenssl -rfiddle -e 'puts Fiddle::Function.new(Fiddle.dlopen(nil)["SSLeay_version"], [Fiddle::TYPE_INT], Fiddle::TYPE_VOIDP).call(0)'ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-darwin13.0]OpenSSL 1.0.1g 7 Apr 2014[~] $ ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION'OpenSSL 1.0.1g 7 Apr 2014

As you can see the system ruby is linked against the OpenSSL included with OS X, and not yet patched by Apple. Ruby 2.1.1 I re-built after after using Homebrew to upgrade my install of OpenSSL.

[~] $ brew list openssl/usr/local/Cellar/openssl/1.0.1g/bin/openssl/usr/local/Cellar/openssl/1.0.1g/bin/c_rehash/usr/local/Cellar/openssl/1.0.1g/include/openssl/ (75 files)/usr/local/Cellar/openssl/1.0.1g/lib/libcrypto.1.0.0.dylib/usr/local/Cellar/openssl/1.0.1g/lib/libssl.1.0.0.dylib/usr/local/Cellar/openssl/1.0.1g/lib/engines/ (12 files)/usr/local/Cellar/openssl/1.0.1g/lib/pkgconfig/ (3 files)/usr/local/Cellar/openssl/1.0.1g/lib/ (4 other files)/usr/local/Cellar/openssl/1.0.1g/share/man/ (1126 files)

First make sure that you have the most current OpenSSL, if you are using Homebrew, just use:

brew upgrade openssl.

Also, make sure to remove the older versions of OpenSSL with brew cleanup openssl

I don't recommend patching the system Ruby, best to use a Ruby version manager, like rbenv or RVM. After updating your SSL, remove and rebuild the versions of Ruby that you use following the normal build/install instructions for your version manager.