Google Play Security Alert – Your app is using an unsafe implementation of the HostnameVerifier

Same here – Insecure Hostname Verifier Detected in APK

Your app is using an unsafe implementation of HostnameVerifier. Please
see this Google Help Center article for details, including the
deadline for fixing the vulnerability. Im not using HostnameVerifier
and not calling setDefaultHostnameVerifier. Moreover – Im using OKHTTP
lib for http-requests. I hope that defining TrustManager will solve
this issue.

Since I’m not subclassing HostnameVerifier or calling setDefaultHostnameVerifier() I assume it relies to some 3rd party lib. Since I can’t detect such lib I think I will try to add a class with following code

HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
    public boolean verify(final String hostname, final SSLSession session) {
        if (/* check if SSL is really valid */)
            return true;
        else
            return false;
    }
});

to my project and will see if it fixes the issue.
So I did it and additionally to every webView I’ve added overridden method

@Override
public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
    // the main thing is to show dialog informing user
    // that SSL cert is invalid and prompt him to continue without 
    // protection: handler.proceed();
    // or cancel: handler.cancel();
    String message;
    switch(error.getPrimaryError()) {
        case SslError.SSL_DATE_INVALID:
            message = ResHelper.getString(R.string.ssl_cert_error_date_invalid);
            break;
        case SslError.SSL_EXPIRED:
            message = ResHelper.getString(R.string.ssl_cert_error_expired);
            break;
        case SslError.SSL_IDMISMATCH:
            message = ResHelper.getString(R.string.ssl_cert_error_idmismatch);
            break;
        case SslError.SSL_INVALID:
            message = ResHelper.getString(R.string.ssl_cert_error_invalid);
            break;
        case SslError.SSL_NOTYETVALID:
            message = ResHelper.getString(R.string.ssl_cert_error_not_yet_valid);
            break;
        case SslError.SSL_UNTRUSTED:
            message = ResHelper.getString(R.string.ssl_cert_error_untrusted);
            break;
        default:
            message = ResHelper.getString(R.string.ssl_cert_error_cert_invalid);
    }
    mSSLConnectionDialog = new MaterialDialog.Builder(getParentActivity())
            .title(R.string.ssl_cert_error_title)
            .content(message)
            .positiveText(R.string.continue_button)
            .negativeText(R.string.cancel_button)
            .titleColorRes(R.color.black)
            .positiveColorRes(R.color.main_red)
            .contentColorRes(R.color.comment_grey)
            .backgroundColorRes(R.color.sides_menu_gray)
            .onPositive(new MaterialDialog.SingleButtonCallback() {
                @Override
                public void onClick(MaterialDialog materialDialog, DialogAction dialogAction) {
                    mSSLConnectionDialog.dismiss();
                    handler.proceed();
                }
            })
            .onNegative(new MaterialDialog.SingleButtonCallback() {
                @Override
                public void onClick(MaterialDialog materialDialog, DialogAction dialogAction) {
                    handler.cancel();
                }
            })
            .build();
    mSSLConnectionDialog.show(); 
}

to the

mWebView.setWebViewClient(new WebViewClient() {
... // other corresponding overridden methods
}

And finally Google says:

SECURITY SCAN COMPLETE
No known vulnerabilities were detected for APK 158.

However I’m not sure what code made it, HostNameVerifier or onReceivedSslError() of mWebView.setWebViewClient. Note: HostNameVerifier.setDefaultHostnameVerifier() should not return true always like it is in your code! It has to implement some logic to check if its all OK with SSL and return true or false. It is essential.

Leave a Comment