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"
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"
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.
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.
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.
@tpickett66 thanks for pointing that out!