Reliable HTTP libraries? (HTTPoison, HTTPotion, Tesla)?

Correct. Most HTTP clients still inherit :ssl’s default of verify: :none, meaning connections to HTTPS URLs silently ignore the server’s certificate:

iex(1)> :httpc.request('https://untrusted-root.badssl.com/')
{:ok,
 {{'HTTP/1.1', 200, 'OK'}, ...}}

At least in recent versions, when passing in verify: :verify_peer and a trust store (e.g. from the certifi package) both chain validation and hostname verification work out-of-the-box:

iex(2)> :httpc.request(:get, {'https://untrusted-root.badssl.com/', []}, [ssl: [verify: :verify_peer, cacertfile: :certifi.cacertfile]], [])
{:error,
 {:failed_connect, ...}}

iex(3)> :httpc.request(:get, {'https://wrong.host.badssl.com/', []}, [ssl: [verify: :verify_peer, cacertfile: :certifi.cacertfile]], [])    
{:error,
 {:failed_connect, ...}}

(There are some known issues with cross-signed and wildcard certs, though; I would recommend using the ssl_verify_fun package for maximum server compatibility)

Edit: the above testing was done with Erlang/OTP 21 (inets 7.0)

9 Likes