SSL Vulnerability in ******** VU#582497

2019-03-22 09:12发布

问题:

Recently received a warning letter that my application security threatened.

  ---------- Forwarded message ----------
    From: CERT Coordination Center <cert@cert.org>
    Subject: SSL Vulnerability in ********* VU#582497
    Cc: cert@cert.org

The letter contains the following information: We've recently been evaluating with CERT Tapioca http://www.cert.org/blogs/certcc/post.cfm?EntryID=203 the use of SSL by Android apps. Through automated testing, we are logging apps that cause traffic to be sent or received over an HTTPS connection that has an invalid SSL certificate chain. The following application has demonstrated this incorrect behavior.

Some caveats that may affect the impact of the test results:

1) We have not yet investigated the content that is sent over HTTPS with an invalid SSL certificate chain. If the information is not sensitive, one might argue that the vulnerability does not really have an impact. However, the other argument is that the use of unvalidated SSL is a vulnerability that needs to be corrected, regardless of the content sent or received.

2) It could be that your application itself uses SSL properly, but it includes a third-party library that itself does improper SSL validation. In such a case, this third-party library would need to be updated. Or if a fix isn't available, the library's author should be notified to let them know that they need to fix the library.

3) Due to the UI automation used in the dynamic testing that we performed, there is a small chance that the application or the browser components used by the application did correctly warn the user before proceeding. If the UI automation did happen to click the button required to proceed despite an invalid certificate, then this could be considered a false positive. If you believe this to be the case, please respond and let us know.

For request, I use robospice-spring-android. ssl usage:

 static {
        try {
            SSLContext sslc = SSLContext.getInstance("TLS");
            TrustManager[] trustManagerArray = {new NullX509TrustManager()};
            sslc.init(null, trustManagerArray, null);
            HttpsURLConnection.setDefaultSSLSocketFactory(sslc.getSocketFactory());
            HttpsURLConnection.setDefaultHostnameVerifier(new NullHostnameVerifier());
        } catch (Exception e) {
        }
    }

private static class NullX509TrustManager implements X509TrustManager {
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }

    private static class NullHostnameVerifier implements HostnameVerifier {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }

Can anyone suggest on this issue. What is my fault?

回答1:

Can anyone suggest on this issue. What is my fault?

You effectively disable any kind of authentication built into TLS. An attacker can thus easily mount a man-in-the-middle attack or a phishing attack, that is listen to and manipulate the encrypted traffic or claim to be the real server.

Such can usually easy be done with ARP or DHCP spoofing inside the local LAN or a public WLAN, so the problem described is not a theoretical but a real problem.

In detail:

        TrustManager[] trustManagerArray = {new NullX509TrustManager()};
        sslc.init(null, trustManagerArray, null);

Here you disable the check if the certificate is signed by a trusted CA. The attacker can now use any self-signed certificate or a certificate signed by an untrusted CA instead of the real one.

        HttpsURLConnection.setDefaultHostnameVerifier(new NullHostnameVerifier());

Here you disable the check to verify the hostname inside the certificate against the host you want to access. Example:

  • the site you want to access is super-secure.example and you bought a certificate for it
  • the attacker has the site attacker.example and bought a certificate for it

Usually the client will verify that the name in the certificate matches the name the client connected to. But you explicitly disabled this check with the code above and thus the attackers certificate gets accepted.

You main fault is probably that you just copied some code from somewhere without understanding what it does. Bad idea in any case, but especially for anything related to security.