httprb / http

HTTP (The Gem! a.k.a. http.rb) - a fast Ruby HTTP client with a chainable API, streaming support, and timeouts
MIT License
3.01k stars 321 forks source link

Respect the SSL context's verify_hostname value #632

Closed colemannugent closed 3 years ago

colemannugent commented 3 years ago

I stumbled upon an issue where http.rb wouldn't respect the verify_hostname value of the current OpenSSL::SSL::SSLContext.

Previously we would unconditionally call post_connection_check, whose only purpose is to verify hostnames, regardless of what verify_hostname was set to. This results in quite a bit of user confusion since one expects hostname verification to be handled by OpenSSL itself rather than by the HTTP library.

Digging through the blames, it looks like this was never implemented properly. Ruby's Net::HTTP fixed the same issue with this pull in January.

This simple change fixes the issue for me and brings http.rb in line with the other Ruby HTTP libraries.

tarcieri commented 3 years ago

This results in quite a bit of user confusion since one expects hostname verification to be handled by OpenSSL itself rather than by the HTTP library.

Yeah, it's a big mess. OpenSSL itself didn't implement hostname verification at all until quite recently, leaving all users of it to reimplement it poorly themselves (and as it were, I ended up rewriting the hostname verification code used by Ruby itself due to numerous problems).

Anyway, approved! Thanks for the fix.

tarcieri commented 3 years ago

Per #633 CI is broken (thanks Travis), but I'm going to go ahead and merge this.

ixti commented 3 years ago

Seems like this PR broke jRuby:


image

tarcieri commented 3 years ago

@ixti aah, unfortunate. Sorry about that.

Seems like it can at least be worked around with reflection.

ixti commented 3 years ago

jRuby has older version of OpenSSL gem bundled in.

ixti commented 3 years ago

https://github.com/httprb/http/pull/634/commits/f8dfb38181be02c973194657242590754eeed51e

tarcieri commented 3 years ago

I was suggesting something like:

if ssl_context.respond_to?(:verify_hostname) && ssl_context.verify_hostname
  @socket.post_connection_check(host)
end
ixti commented 3 years ago

@tarcieri :+1: Will do so!