Java Playstore漏洞HostnameVerifier接口的不安全实现

Java Playstore漏洞HostnameVerifier接口的不安全实现,java,android,google-play,okhttp,android-security,Java,Android,Google Play,Okhttp,Android Security,我知道这是个老话题。但我已经尝试了大多数答案中的所有解决方案。我在两天内上传了10次该应用程序,并一直收到来自谷歌Play支持的相同通知。 当我收到来自谷歌的通知时,我正在使用okhttp3的内置主机名验证程序。但在多次失败后,我更新了所有依赖项并添加了主机名验证程序。更新仍然被拒绝。这是我的ApiClient课程 public class APIClient { private static Retrofit retrofit = null; public static ApiInter

我知道这是个老话题。但我已经尝试了大多数答案中的所有解决方案。我在两天内上传了10次该应用程序,并一直收到来自谷歌Play支持的相同通知。

当我收到来自谷歌的通知时,我正在使用okhttp3的内置主机名验证程序。但在多次失败后,我更新了所有依赖项并添加了主机名验证程序。更新仍然被拒绝。这是我的ApiClient课程

public class APIClient {

private static Retrofit retrofit = null;

public static ApiInterface getAPIClient() {
    if (retrofit == null) {
        retrofit = new Retrofit
                .Builder()
                .baseUrl(BuildConfig.BASE_URL)
                .client(getHttpClient())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    return retrofit.create(ApiInterface.class);
}

private static OkHttpClient getHttpClient() {

    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
    okHttpClientBuilder.cache(new Cache(MvpApplication.getInstance().getCacheDir(), 10 * 1024 * 1024)) // 10 MB
            .connectTimeout(10, TimeUnit.MINUTES)
            .addNetworkInterceptor(new AddHeaderInterceptor())
            .addNetworkInterceptor(new StethoInterceptor())
            .readTimeout(10, TimeUnit.MINUTES)
            .writeTimeout(10, TimeUnit.MINUTES)
            .addInterceptor(interceptor);

    okHttpClientBuilder.hostnameVerifier((hostname, session) -> {

        Certificate[] certs;
        try {
            certs = session.getPeerCertificates();
        } catch (SSLException e) {
            return false;
        }
        X509Certificate x509 = (X509Certificate) certs[0];
        // We can be case-insensitive when comparing the host we used to
        // establish the socket to the hostname in the certificate.
        String hostName = hostname.trim().toLowerCase(Locale.ENGLISH);
        // Verify the first CN provided. Other CNs are ignored. Firefox, wget,
        // curl, and Sun Java work this way.
        String firstCn = getFirstCn(x509);
        System.out.println(TAG + ": firstCn: "+firstCn);
        if (matches(hostName, firstCn)) {
            return true;
        }
        for (String cn : getDNSSubjectAlts(x509)) {
            if (matches(hostName, cn)) {
                return true;
            }
        }
        return false;

    });

    return okHttpClientBuilder.build();


}

private static String getFirstCn(X509Certificate cert) {
    String subjectPrincipal = cert.getSubjectX500Principal().toString();
    for (String token : subjectPrincipal.split(",")) {
        int x = token.indexOf("CN=");
        if (x >= 0) {
            return token.substring(x + 3);
        }
    }
    return null;
}

private static class AddHeaderInterceptor implements Interceptor {
    @Override
    public Response intercept(@NonNull Chain chain) throws IOException {
        Request.Builder builder = chain.request().newBuilder();
        builder.addHeader("X-Requested-With", "XMLHttpRequest");
        builder.addHeader("Authorization",
                SharedHelper.getKey(MvpApplication.getInstance(), "access_token"));
        Log.d("TTT access_token", SharedHelper.getKey(MvpApplication.getInstance(), "access_token"));
        return chain.proceed(builder.build());
    }
}
有人能建议我在Play Store上发布版本之前检查可能的漏洞,或者绕过此问题的任何方法吗

以下是项目中HostnameVerifier的实现

我在发射前报告中收到了17次警告。其中一些是由于okhttp。这是一个警告

StrictMode policy violation: android.os.strictmode.NonSdkApiUsedViolation: Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setHostname(Ljava/lang/String;)V
at android.os.StrictMode.lambda$static$1(StrictMode.java:428)
at android.os.-$$Lambda$StrictMode$lu9ekkHJ2HMz0jd3F8K8MnhenxQ.accept(Unknown Source:2)
at java.lang.Class.getDeclaredMethodInternal(Native Method)
at java.lang.Class.getPublicMethodRecursive(Class.java:2075)
at java.lang.Class.getMethod(Class.java:2063)
at java.lang.Class.getMethod(Class.java:1690)
at okhttp3.internal.platform.android.AndroidSocketAdapter.<init>(AndroidSocketAdapter.kt:36)
at okhttp3.internal.platform.android.StandardAndroidSocketAdapter.<init>(StandardAndroidSocketAdapter.kt:34)
at okhttp3.internal.platform.android.StandardAndroidSocketAdapter$Companion.buildIfSupported(StandardAndroidSocketAdapter.kt:59)
at okhttp3.internal.platform.android.StandardAndroidSocketAdapter$Companion.buildIfSupported$default(StandardAndroidSocketAdapter.kt:52)
at okhttp3.internal.platform.AndroidPlatform.<init>(AndroidPlatform.kt:47)
at okhttp3.internal.platform.AndroidPlatform$Companion.buildIfSupported(AndroidPlatform.kt:160)
at okhttp3.internal.platform.Platform$Companion.findAndroidPlatform(Platform.kt:219)
at okhttp3.internal.platform.Platform$Companion.findPlatform(Platform.kt:212)
at okhttp3.internal.platform.Platform$Companion.access$findPlatform(Platform.kt:169)
at okhttp3.internal.platform.Platform.<clinit>(Platform.kt:170)
at okhttp3.OkHttpClient.<init>(OkHttpClient.kt:237)
at okhttp3.OkHttpClient$Builder.build(OkHttpClient.kt:1069)
at com.shadigipay.shadrivedriver.data.network.APIClient.getHttpClient(APIClient.java:172)
at com.shadigipay.shadrivedriver.data.network.APIClient.getAPIClient(APIClient.java:56)
at com.shadigipay.shadrivedriver.ui.activity.splash.SplashPresenter.checkVersion(SplashPresenter.java:33)
at com.shadigipay.shadrivedriver.ui.activity.splash.SplashActivity.checkVersion(SplashActivity.java:98)
at com.shadigipay.shadrivedriver.ui.activity.splash.SplashActivity.onResume(SplashActivity.java:205)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1412)
at androidx.test.runner.MonitoringInstrumentation.callActivityOnResume(MonitoringInstrumentation.java:1)
at android.app.Activity.performResume(Activity.java:7300)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3814)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3854)
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:51)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6718)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
StrictMode策略冲突:android.os.StrictMode.NonSdkApiUsedViolation:Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setHostname(Ljava/lang/String;)V
在android.os.stricmode.lambda$static$1(stricmode.java:428)
在android.os.-$$Lambda$StrictMode$lu9ekkHJ2HMz0jd3F8K8MnhenxQ.accept(未知来源:2)
位于java.lang.Class.getDeclaredMethodInternal(本机方法)
位于java.lang.Class.getPublicMethodRecursive(Class.java:2075)
位于java.lang.Class.getMethod(Class.java:2063)
位于java.lang.Class.getMethod(Class.java:1690)
在okhttp3.internal.platform.android.AndroidSocketAdapter。(AndroidSocketAdapter.kt:36)
在okhttp3.internal.platform.android.StandardAndroidSocketAdapter。(StandardAndroidSocketAdapter.kt:34)
在okhttp3.internal.platform.android.StandardAndroidSocketAdapter$Companion.buildIfSupported(StandardAndroidSocketAdapter.kt:59)
在okhttp3.internal.platform.android.StandardAndroidSocketAdapter$Companion.buildIfSupported$default(StandardAndroidSocketAdapter.kt:52)
在okhttp3.internal.platform.AndroidPlatform.(AndroidPlatform.kt:47)
在okhttp3.internal.platform.AndroidPlatform$Companion.buildIfSupported上(AndroidPlatform.kt:160)
在okhttp3.internal.platform.platform$Companion.findAndroidPlatform(platform.kt:219)上
在okhttp3.internal.platform.platform$Companion.findpplatform(platform.kt:212)上
在okhttp3.internal.platform.platform$Companion.access$findpplatform(platform.kt:169)
在okhttp3。内部。平台。平台。(平台。kt:170)
在okhttp3.OkHttpClient(OkHttpClient.kt:237)
位于okhttp3.OkHttpClient$Builder.build(OkHttpClient.kt:1069)
位于com.shadigipay.shadrivedriver.data.network.APIClient.getHttpClient(APIClient.java:172)
位于com.shadigipay.shadrivedriver.data.network.APIClient.getAPIClient(APIClient.java:56)
位于com.shadigipay.shadrivedriver.ui.activity.splash.SplashPresenter.checkVersion(SplashPresenter.java:33)
位于com.shadigipay.shadrivedriver.ui.activity.splash.SplashActivity.checkVersion(SplashActivity.java:98)
位于com.shadigipay.shadrivedriver.ui.activity.splash.SplashActivity.onResume(SplashActivity.java:205)
位于android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1412)
位于androidx.test.runner.MonitoringInstrumentation.callActivityOnResume(MonitoringInstrumentation.java:1)
在android.app.Activity.performResume上(Activity.java:7300)
位于android.app.ActivityThread.performResumeActivity(ActivityThread.java:3814)
位于android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3854)
在android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:51)中
位于android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145)
在android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)中
在android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816)
位于android.os.Handler.dispatchMessage(Handler.java:106)
位于android.os.Looper.loop(Looper.java:193)
位于android.app.ActivityThread.main(ActivityThread.java:6718)
位于java.lang.reflect.Method.invoke(本机方法)
位于com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
我正在使用okhttp 4.9.0和改进版2.9.0

不要编写自己的HostnameVerifier,这样做只会降低安全性,降低它们获得批准的可能性。您需要找到他们正在标记的HostnameVerifier的实现,并停止使用它

您还应该按照照片中链接的说明进行操作

用android安全性标记此问题,并可能使用他们提供的表单与他们联系

还可以编辑您的问题以显示您在项目中的实现


也许您的应用程序或第三方库中有调试实现?我的代码中没有这样的实现。有没有办法知道任何库项目中是否存在漏洞?是否有可能在构建中包含任何测试源?你能在你的IDE上发布一个屏幕截图,显示你的应用程序中这个界面的实现吗?我从谷歌得到的官方答案是,需要一个诊断工具,如下所示:“如果你对这个漏洞有技术问题,你可以发布到Stack Overflow并使用标签“android security”我们在这里无能为力。我们得到的唯一提示是,它可能与braintree/paypal库有关。你们使用它吗?我得到的回应是paypal是罪魁祸首。另外,我的一个应用程序已经发布。你们的项目中有网络安全配置xml来过滤主机名吗?我已经添加了实现。我还联系了Google Play团队。希望他们在周末后回复。我查看了Alpha测试报告,发现有几个政策问题都与Google Library更新有关。我将minSdk从16改为19,因为一些功能在下面的手机上不起作用。之后我上传了一个新的apb,还没有收到拒绝邮件。但他们我也还没有批准发布。一旦批准/拒绝,我会查清楚。祝你好运。谢谢