Skip to content Skip to sidebar Skip to footer

Google Play Security Alert - Your App Is Using An Unsafe Implementation Of The Hostnameverifier

Recently one of my app got a security alert from Google Play as below. You app is using an unsafe implementation of the HostnameVerifier. And refer a link to Google Play Help Cente

Solution 1:

HttpsURLConnection.setDefaultHostnameVerifier(newHostnameVerifier(){ 
    publicbooleanverify(String arg0, SSLSession arg1) {
        returntrue;
}}); 

This code effectively removes the protection of HTTPS from your connections. You need to delete it.

Disabling hostname verification allows anyone on the network to view and tamper with your network traffic by conducting a Man In The Middle Attack.

Solution 2:

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(newHostnameVerifier() {
    publicbooleanverify(final String hostname, final SSLSession session) {
        if (/* check if SSL is really valid */)
            returntrue;
        elsereturnfalse;
    }
});

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
publicvoidonReceivedSslError(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
                publicvoidonClick(MaterialDialog materialDialog, DialogAction dialogAction) {
                    mSSLConnectionDialog.dismiss();
                    handler.proceed();
                }
            })
            .onNegative(new MaterialDialog.SingleButtonCallback() {
                @Override
                publicvoidonClick(MaterialDialog materialDialog, DialogAction dialogAction) {
                    handler.cancel();
                }
            })
            .build();
    mSSLConnectionDialog.show(); 
}

to the

mWebView.setWebViewClient(newWebViewClient() {
... // 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.

Solution 3:

Please check my code I have only verified domains that my app uses. In your code you must verify all domains your app uses. I have used my server and Fabric.com so my code is below

HttpsURLConnection.setDefaultHostnameVerifier(newHostnameVerifier() {
    @Overridepublicbooleanverify(String hostname, SSLSession arg1) {
        if (hostname.equalsIgnoreCase("api.my.com") || 
            hostname.equalsIgnoreCase("api.crashlytics.com") || 
            hostname.equalsIgnoreCase("settings.crashlytics.com")) {
            returntrue;
        } else {
            returnfalse;
        }
    }
});

Solution 4:

On google play console go to Release Management -> Select apk version -> Security tab. There you will see list of security issues with that apk along with class in your code that's causing that security issue where ever possible.

enter image description here

Solution 5:

If you're using Braintree for Paypal payment.

Unsafe implementation of the HostnameVerifier interface - Google policy violation can also be caused due to the latest Braintree credentials update.

Please update below credentials and URL in build.gradle(Project)

Old Credentials

url  "https://cardinalcommerce.bintray.com/android"
username 'braintree-team-sdk@cardinalcommerce'
password '220cc9476025679c4e5c843666c27d97cfb0f951'

New Credentials

allprojects {
    repositories {
        google()
        jcenter()
        maven {
            url "https://cardinalcommerceprod.jfrog.io/artifactory/android"
            credentials {
                username 'braintree_team_sdk'
                password 'AKCp8jQcoDy2hxSWhDAUQKXLDPDx6NYRkqrgFLRc3qDrayg6rrCbJpsKKyMwaykVL8FWusJpp'
            }
        }
    }
}

If you're using the Google Play Services Gradle plugin, you will also need to add this to your build.gradle to avoid a dependency resolution issue:

components.all {
    allVariants {
        withDependencies { deps ->
            deps.each { dep ->if (dep.group == 'net.minidev' && dep.name =='json-smart') {
                    dep.version {
                        prefer "2.3"
                    }
                    dep.because "resolving dependencies issue"
                }
            }
        }
    }
}

StackOverflow: Braintree Drop-in UI: ERROR: Failed to resolve: org.jfrog.cardinalcommerce.gradle:cardinalmobilesdk:2.2.1-2?

For more info: https://developer.paypal.com/braintree/docs/guides/3d-secure/client-side/android/v3#generate-a-client-token

Related Git Thread regarding: https://github.com/braintree/braintree-android-drop-in/issues/219

Post a Comment for "Google Play Security Alert - Your App Is Using An Unsafe Implementation Of The Hostnameverifier"