0

Hello my application is live and it is using "https" protocol. The Google Play Team throws warning as below.

"Your app(s) listed at the end of this email use an unsafe implementation of the interface X509TrustManager. Specifically, the implementation ignores all SSL certificate validation errors when establishing an HTTPS connection to a remote host, thereby making your app vulnerable to man-in-the-middle attacks. An attacker could read transmitted data (such as login credentials) and even change the data transmitted on the HTTPS connection. If you have more than 20 affected apps in your account, please check the Developer Console for a full list.

To properly handle SSL certificate validation, change your code in the checkServerTrusted method of your custom X509TrustManager interface to raise either CertificateException or IllegalArgumentException whenever the certificate presented by the server does not meet your expectations. Google Play will block publishing of any new apps or updates containing the unsafe implementation of the interface X509TrustManager."

In my project I am using custom http client to handle HTTPS instead default httpClient. My code is as below.

    public static HttpClient getNewHttpClient() {
            try
            {
                KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
                trustStore.load(null, null);

                MySSLSocketFactory sf = new MySSLSocketFactory(trustStore);
                sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

                HttpParams params = new BasicHttpParams();
                HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
                HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

                SchemeRegistry registry = new SchemeRegistry();
                registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
                registry.register(new Scheme("https", sf, 443));

                ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

                return new DefaultHttpClient(ccm, params);
            }
            catch (Exception e)
            {
                return new DefaultHttpClient();
            }
        }

public static class MySSLSocketFactory extends SSLSocketFactory {
        SSLContext sslContext = SSLContext.getInstance("TLS");

        public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
            super(truststore);

            TrustManager tm = new X509TrustManager() {
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

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

                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            };

            sslContext.init(null, new TrustManager[] { tm }, null);
        }

        @Override
        public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
            return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
        }

        @Override
        public Socket createSocket() throws IOException {
            return sslContext.getSocketFactory().createSocket();
        }
    }

How to overcome with this problem? Hoping for favorable answers.

  • are you use webview? – Pratik Tank Mar 07 '16 at 04:54
  • No. I'm getting webservice response from https link. –  Mar 07 '16 at 05:03
  • Do you have any code that does what this email suggests with regard to transactions over HTTPS? It's considered unsafe, and sometimes added by devs by accident. – Doug Stevenson Mar 07 '16 at 05:09
  • @DougStevenson Or, and I suspect much more common only, 'only for testing'. It is terrifying to consider how may insecure applications may have been put into production due to these insecure `TrustManagers`. And it's great that Google is putting some effort into detecting them. – user207421 Mar 07 '16 at 05:14
  • @DougStevenson , please check my edited question, I updated it with used code. –  Mar 07 '16 at 05:14
  • 2
    see this http://stackoverflow.com/a/6378872/4146722 – Pratik Tank Mar 07 '16 at 05:18

2 Answers2

3

Now that you have posted the code concerned, it is difficult to see what part of the quoted message you don't understand.

The fix is simply to remove the TrustManager part of the code altogether, root and branch, and use the default one, and then deal with whatever problems may then arise in the proper way, by adjusting the contents of the truststore also as to trust all the certificates you need to trust that aren't already trusted by default. If any, which there shouldn't be.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • If i'll remove TrustManager part from my code then how can i deal with HTTPS server request. Actually i'm using HTTPS webservices to post data on server. –  Mar 07 '16 at 05:21
  • When I post an answer I do expect it to be read beyond the first half sentence of the second paragraph. – user207421 Mar 07 '16 at 05:24
  • Yes I have just removed the TrustManager part of the code and implement HttpURLConnection instead of DefaullHttpClient. –  Mar 07 '16 at 05:56
0

Why do you need custom SSLSocketFactory. You can use DefaultHttpClient and that will handle all https by default. Just for your info, that HttpClient is deprecated and use HttpURLConnection.

user207421
  • 305,947
  • 44
  • 307
  • 483
cowboy007
  • 43
  • 3