60

I try to access a file with open-uri over an https connection. Unfortunately somethings wrong with the certificate, I get a certificate verify failed error. I can't do anything about that, so I have to bypass the verification.

I found this answer

I don't want to / can't change the oen-uri.rb on the server, and I'm running Ruby 1.8.6.

How do I change the verify mode? Or more exactly where do I change it?

Where can I put this?

if target.class == URI::HTTPS  
 require 'net/https'  
 http.use_ssl = true   
 http.verify_mode = OpenSSL::SSL::VERIFY_NONE  
 store = OpenSSL::X509::Store.new  
 store.set_default_paths  
 http.cert_store = store
end

or the dirty hack: where can I put this?

OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
Roland Studer
  • 4,315
  • 3
  • 27
  • 43

7 Answers7

83

Warning, do not do this in production, you are disabling SSL completely this way.

If you really don't want the additional security of using certificate verification, and can upgrade to Ruby 1.9.3p327+, you can pass the ssl_verify_mode option to the open method. Here for example is how I'm doing it:

request_uri=URI.parse('myuri?that_has=params&encoded=in_it&optionally=1')

# The params incidentally are available as a String, via request_uri.query
output = open(request_uri, {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE})
obj = JSON.parse output.readlines.join("")
Roland Studer
  • 4,315
  • 3
  • 27
  • 43
sameers
  • 4,855
  • 3
  • 35
  • 44
  • @JimmyDean 2.2.1p85 on mac os x here, verify_mode doesn't work. – nurettin Aug 19 '15 at 19:02
  • @nurettin - You are 100% correct. I was looking at the wrong gem. HTTPClient it's verify_mode. I have removed by comment to not clutter with wrong information. Thanks for pointing this out. http://www.rubydoc.info/gems/httpclient/HTTPClient%2FSSLConfig%3Averify_mode – JamesDeHart Aug 20 '15 at 10:57
  • I wanted to add that there are valid reasons for wanting to disable it. I can use wget to do so, too, by the way. I was trying to obtain a file listing of slackware package from this URL: https://slackware.nl/alien-kde/current/latest/x86_64/FILELIST.TXT but open-uri failed since this used a self-signed cert. I understand that we should not trust random folks, but the dude who set it up is just an oldschool slackware user, and I could see that file in my browser already, so it was only ruby that would give me problems here, due to the default behaviour of openssl.That is why flexibility matters – shevy Jun 14 '19 at 16:24
45

Found it out myself now: I used the dirty hack, which works fine for me.

I had to put it into: yourrailsapp/initalizers/

There I created a bypass_ssl_verification_for_open_uri.rb

And put:

OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
Roland Studer
  • 4,315
  • 3
  • 27
  • 43
  • 11
    If you get a 'dynamic constant assignment' error do the following : OpenSSL::SSL.const_set(:VERIFY_PEER, OpenSSL::SSL::VERIFY_NONE) – Sam Feb 04 '14 at 18:58
  • 5
    And to avoid even the `warning: already initialized constant OpenSSL::SSL::VERIFY_PEER` warning, use `remove_const` to first remove the constant before adding it back in. This is hard to type into a comment so [check out this gist instead](https://gist.github.com/siruguri/66926b42a0c70ef7119e). – sameers Apr 14 '15 at 18:50
  • Prefer @sameers answer if you are using ruby 1.9.3p327+ – jvenezia Apr 27 '15 at 13:46
  • 5
    that answer is a joke – Tomasz Nazar May 30 '17 at 07:44
  • Hi I regularly get downvotes for this answer. Can anybody explain me why? I understand that it's not a nice solution, but the actual question at that tim for me, was where to put the bypass, as I had only a very basic understanding of rails. Thx – Roland Studer May 09 '18 at 14:09
  • 3
    @RolandStuder the downvotes are for suggesting `OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE`. You're redefining a constant (bad) in some very important security related code (very very bad). If _anyone_ includes your code (or the code written by anyone foolish enough copy-paste your solution in to their code), then they've instantly disabled SSL verification )without even realising it). It would be great if you could update your answer to include some kind of warning or disclaimer. *No one should ever do this in public or production code* – aidan Oct 04 '18 at 05:03
  • @aidan Thanks for the feedback. Ok, I added a more clear disclaimer. I know disabling SSL is BAAAD. But the answer definitely answers the question :-) I was actually unsure, whether there was something else bad. Enjoy your day! – Roland Studer Oct 05 '18 at 11:13
19

it's good (it may spawn uninitialized constant OpenSSL (NameError)) to put require 'openssl' before that line, so

app/config/initializers/bypass_ssl_verification_for_open_uri.rb (filename of initializer doesn' matter)

require 'openssl'
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE

Ivan Stana
  • 656
  • 6
  • 14
  • 3
    How can I use it on a script? I have tried it and I got 'warning: already initialized constant VERIFY_PEER.' and it does not work – daitangio Jan 04 '12 at 09:34
  • it seems, that constant VERIFY_PEER is already somewhere defined before, you get certify verification error? – Ivan Stana Jan 28 '12 at 12:04
  • 1
    Still VERY relevant and helpful in 2020 and Rails 5 when using Docker, and ngrok, to replicate a production environment where server-to-server communication occurs over SSL on your development machine. (Pretty sure it is Puma as a webserver that is being so strict about the certificate.) HOWEVER: PUTTING THE CODE ABOVE INSIDE `if Rails.env.development?` IS VITAL TO ENSURE IT NEVER DISABLES SSL IN YOUR PRODUCTION APP – jpw Oct 17 '20 at 19:44
13

As you mentioned yourself, this is a dirty hack. Obviously, disabling SSL certificate verification is not a good idea.

There is a very helpful article by Mislav Marohnić, which goes into great detail why this is bad and how to address this properly.

In summary, you mostly get the SSL verify error if:

  1. the certificate is valid, but your system does not have the necessary root certificate for verification.
  2. the certificate is self-signed, e.g. in your company and you need to trust it
  3. you're subject to a man-in-the-middle attack

For me the first case applied, and simply updating the ca-certificates package on my Ubuntu system did the trick.

A great tool to track down your SSL error is the ssl doctor script.

Dave Powers
  • 2,051
  • 2
  • 30
  • 34
pymkin
  • 4,304
  • 1
  • 21
  • 18
4

It's your call, but setting VERIFY_PEER to NONE is basically equivalent to disabling TLS altogether and connecting over plaintext HTTP. It makes man in the middle attacks trivial, and will not pass a PCI audit.

Bibek Sharma
  • 3,210
  • 6
  • 42
  • 64
3

Seems like a good candidate for inclusion in environment.rb, or if this hack is only necessary in particular environments, then in their individual config files.

Patrick McKenzie
  • 4,066
  • 24
  • 23
3

A weak but controlled way is

class XMLRPC::Client
 # WEAK: Enrich the Client with a method for disabling SSL VERIFICATION
 # See /usr/lib/ruby/1.9.1/xmlrpc/client.rb:324
 # Bad hack but it works
 def disableSSLVerification
   @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
   warn "Proxyman SSL Verification disabled"
 end
end

Then you simply call

client.disableSSLVerification()
daitangio
  • 583
  • 1
  • 6
  • 18