beatrice
beatrice

Reputation: 4411

How to use HostnameVerifier?

I am experimenting right now with SSL configs using KeyManager and TrustManager, everything seems clear to me except the HostNameVerifier part.

I have read the followings:
https://docs.oracle.com/javase/7/docs/api/javax/net/ssl/HostnameVerifier.html
https://lightbend.github.io/ssl-config/HostnameVerification.html

So basically it comes in effect when the requested URL and the URL in the cert are mismatch.

What is the best practice to handle this?

 new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
          // some code
        }
    };

From security(like man in the middle attack) point of view I think it must return false all the time.But in this case what is the purpose of this whole thing?
However surfing on the internet most of the time I come accross solutions that return a raw 'true' (without any work on the arguments).

So its confusing to me when,why and how should I use it.

Could you elaborate it please?

Upvotes: 10

Views: 22501

Answers (3)

Hack5
Hack5

Reputation: 3601

If you're just trying to make the system trust a specific certificate in place of the expected hostname, you could try this (Kotlin) code:

            return if (hostname == "proxy.example.com") { // the host that is being connected to over TCP
                val cert = session.peerCertificates[0] as? X509Certificate ?: return false
                cert.subjectAlternativeNames.contains(listOf(2, "subject.example.com")) // the certificate that is being served
            } else {
                false
            }

It won't work for some old certificates that use CN identification only (not SAN), but this would be trivial to fix.

Upvotes: 1

galian
galian

Reputation: 890

Check if the session host is what we expect.

public boolean verify(String hostname, SSLSession session) {
   return hostname.equals(session.getPeerHost());
}

Upvotes: 4

Steffen Ullrich
Steffen Ullrich

Reputation: 123300

From security(like man in the middle attack) point of view I think it must return false all the time.

Almost correct. This method is only called if the default verification detects a problem. In almost all cases such a problem means that the connection should be aborted to keep it secure.

However surfing on the internet most of the time I come accross solutions that return a raw 'true' (without any work on the arguments).

This is wrong almost every time. The authors of such code usually don't understand the implications (possible MITM as you correctly said) and just want their code to work somehow. Yes, it will work but it will also work when it should not, i.e. it is insecure.

Typical reasons that the default verification fails are that the server is improperly configured with the wrong certificate or that the server is accessed with the wrong hostname (i.e. not the one in the certificate).

So its confusing to me when,why and how should I use it.

You should use it only if you know that the host is returning a certificate with the wrong subject but you also know what exactly will be wrong and will properly verify this expectation inside your implementation.

Of course, it is much better to not work around in all applications accessing the server but instead to fix the real problem. Depending on the real cause of the problem this usually means either fixing the certificate at the server or fixing the hostname used to access the server.

Upvotes: 11

Related Questions