Search code examples
rubysoapsslsavonhttpi

SSL mode flags - verification of certificates: is it safe to use :none?


I am writing a soap request over SSL using Savon and HTTPi, a Ruby soap client and an interface for Ruby HTTP clients, respectively. Here's the code:

client = Savon::Client.new(original_class.constantize.wsdl_url)
client.http.auth.ssl.cert_key_file = "path_to_the_key"
client.http.auth.ssl.cert_key_password = 'secret'
client.http.auth.ssl.cert_file = "path_to_the_certification"
client.http.auth.ssl.verify_mode = :none
@response = client.request :ins0, action do
  soap.body = encoded_body
end

That's the only way I get this to work. But, I know that there is three others verify modes, which are:

  • :peer (SSL_VERIFY_PEER)
  • :fail_if_no_peer_cert (SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
  • :client_once (SSL_VERIFY_CLIENT_ONCE)

If I change the verify mode to any other of the above, I get this error:

OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

Then comes my questions (among others I have):

  • Am I doing wrong if I keep the verify mode to :none? Is there any lack of security?
  • What does the error really mean? That my code is wrong or that my certificate (which is self-assigned --- I am in development environment) is not good?

I read the OpenSSL documentation about verify modes:

http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html

About SSL_VERIFY_NONE, on Client Mode, says:

The result of the certificate verification process can be checked after the TLS/SSL handshake using the SSL_get_verify_result(3) function. The handshake will be continued regardless of the verification result.

Should I be worried about it? Should I see verify mode :none as a dangerous thing?

I am asking that because since I can't make it work with the others verify modes, I would like to release the soap request over SSL feature the way it is working now. But I surely wouldn't do it if that could be dangerous.


Solution

  • It is NOT safe to set verify mode to :none (SSL_VERIFY_NONE). This opens up the code to being susceptible to man-in-the-middle attacks. With :none, there will be not server authentication. If an attacker intercepts the connection from my client, my client will not detect the difference and will give any sensitive data communicated through this socket to the attacker.

    The mode flags :fail_if_not_peer_cert and :client_once are only for a server; meaning nothing to the client, it ignores them.

    For client purpose, :peer (SSL_VERIFY_PEER) is the only one the matters. In order to use :peer, I need to have the root certificate used by the certificate in the client trustedstore.

    A big thanks to Dave Thompson from OpenSSL User Support Mailing List. After I joined this list, I finally got help.