Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yemster/0848c37a6a280eb1b626dcbcff92dc62 to your computer and use it in GitHub Desktop.
Save yemster/0848c37a6a280eb1b626dcbcff92dc62 to your computer and use it in GitHub Desktop.
Securing Ruby's OpenSSL

Are your Ruby HTTPS API calls secure?

Let's check:

2.0.0-p481 :001 > OpenSSL::SSL::SSLContext::DEFAULT_PARAMS
 => {:ssl_version=>"SSLv23", :verify_mode=>1, :ciphers=>"ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW", :options=>-2147482625}
2.0.0-p481 :002 > rating = JSON.parse(RestClient::Resource.new("https://www.howsmyssl.com/a/check" ).get)['rating']
 => "Bad"

Fix it!

2.0.0-p481 :003 > OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:options] |= OpenSSL::SSL::OP_NO_COMPRESSION
 => -2147351553
2.0.0-p481 :004 > OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:ciphers] = "TLSv1.2:!aNULL:!eNULL"
 => "TLSv1.2:!aNULL:!eNULL"
2.0.0-p481 :005 > OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:ssl_version] ="TLSv1_2"
 => "TLSv1_2"
2.0.0-p481 :006 > rating = JSON.parse(RestClient::Resource.new("https://www.howsmyssl.com/a/check" ).get)['rating']
 => "Probably Okay"

Explanation

OpenSSL::SSL::OP_NO_COMPRESSION protects against CRIME.

TLSv1.2:!aNULL:!eNULL defines the set of cipher suites that your client will use during negotiation. This ensures that insecure cipher suites are not included. OpenSSL::SSL::OP_NO_SSLv2 and OpenSSL::SSL::OP_NO_SSLv3 as well

TLSv1_2 does nothing as this is just a preference. The set of ciphers we chose will only work with TLSv1.2. To explicitly disable SSLv2 and SSLv3 you can additionally set OpenSSL::SSL::OP_NO_SSLv2 and OpenSSL::SSL::OP_NO_SSLv3. TLSv1.2 and its ciphers will protect against POODLE, BEAST.

But does my OpenSSL have vulnerabilities?

Let's find out what version we're on:

2.0.0-p481 :007 > OpenSSL::OPENSSL_VERSION
 => "OpenSSL 1.0.1g 7 Apr 2014"

Then check the openssl vulnerabilities page or search the NIST CVE database for your version of OpenSSL.

Protip: CPE format: cpe:/:openssl:openssl:1.0.1g

That's not good. I installed ruby with RVM and openssl with homebrew so I need to update both:

~ $ brew update
~ $ brew upgrade openssl
~ $ brew link openssl --force
~ $ rvm reinstall all --with-openssl-dir=/usr/local/opt/openssl/lib

I had problems with --autolibs=homebrew not linking to my homebrew openssl, but the --with-openssl-dir option fixed that.

Notes

Forcing TLSv1.2 may break your app. To see the list of supported ciphers you can use a webservice like...

JSON.parse(Faraday.get("https://www.howsmyssl.com/a/check").body)['given_cipher_suites']

or OpenSSL::Cipher.ciphers. I've found the web service to be more informative.

Hope that helps. I'd be very interested if there are better ways to do this or information I'm missing. Hit me up on twitter @tam7t or leave a comment below.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment