If a HostnameVerifier always returns true it will not verify the hostname at all. This allows an attacker to perform a Man-in-the-middle attack against the application therefore breaking any security Transport Layer Security (TLS) gives. An attack would look like this: 1. The program connects to https://example.com. 2. The attacker intercepts this connection and presents one of their valid certificates they control, for example one from Let's Encrypt. 3. Java verifies that the certificate has been issued by a trusted certificate authority. 4. Java verifies that the certificate has been issued for the host example.com, which will fail because the certificate has been issued for malicious.domain. 5. Java wants to reject the certificate because the hostname does not match. Before doing this it checks whether there exists a HostnameVerifier. 6. Your HostnameVerifier is called which returns true for any certificate so also for this one. 7. Java 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 use an open verifier to solve a configuration problem with TLS/HTTPS you should solve the configuration problem instead.
  • 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 Security Guide for TLS/HTTPS.
  • Further Information on Hostname Verification.
  • OWASP: CWE-297.