If a HostnameVerifier always returns true it will not verify the hostname at all. This stops Transport Layer Security (TLS) providing any security and allows an attacker to perform a man-in-the-middle attack against the application.

An attack might look like this:

  1. The program connects to https://example.com.
  2. The attacker intercepts this connection and presents an apparently-valid certificate of their choosing.
  3. The TrustManager of the program verifies that the certificate has been issued by a trusted certificate authority.
  4. The Java HTTPS library checks whether the certificate has been issued for the host example.com. This check fails because the certificate has been issued for a domain controlled by the attacker, for example: malicious.domain.
  5. The HTTPS library wants to reject the certificate because the hostname does not match. Before doing this it checks whether a HostnameVerifier exists.
  6. Your HostnameVerifier is called which returns true for any certificate so also for this one.
  7. The program proceeds with the connection since your HostnameVerifier accepted it.
  8. The attacker can now read the data your program sends to https://example.com and/or alter its replies while the program thinks the connection is secure.

Do not use an open HostnameVerifier. If you have a configuration problem with TLS/HTTPS, you should always solve the configuration problem instead of using an open verifier.

In the first (bad) example, the HostnameVerifier always returns true. This allows an attacker to perform a man-in-the-middle attack, because any certificate is accepted despite an incorrect hostname. In the second (good) example, the HostnameVerifier only returns true when the certificate has been correctly checked.

  • Android developers: Security with HTTPS and SSL.
  • Terse systems blog: Fixing Hostname Verification.