问题描述
我知道这是一个老话题.但是我尝试了大多数答案中的所有解决方案.我在2天内上传了10次该应用,并一直收到Google Play支持的相同通知.
收到Google发送的通知后,我使用的是okhttp3的内置主机名验证程序.但是在发生多次故障之后,我更新了所有依赖项并添加了主机名验证程序.仍然该更新已被拒绝.这是我的ApiClient类.
公共类APIClient {私有静态Retrofit Retrofit = null;公共静态ApiInterface getAPIClient(){if(retrofit == null){改造=新改造.Builder().baseUrl(BuildConfig.BASE_URL).client(getHttpClient()).addCallAdapterFactory(RxJava2CallAdapterFactory.create()).addConverterFactory(GsonConverterFactory.create()).建造();}返回retrofit.create(ApiInterface.class);}私有静态OkHttpClient getHttpClient(){HttpLoggingInterceptor拦截器= new HttpLoggingInterceptor();拦截器.setLevel(HttpLoggingInterceptor.Level.BODY);OkHttpClient.Builder okHttpClientBuilder =新的OkHttpClient.Builder();okHttpClientBuilder.cache(新的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)-> {证书[]证书;尝试 {certs = session.getPeerCertificates();} catch(SSLException e){返回false;}X509Certificate x509 =(X509Certificate)certs [0];//在比较我们以前使用的主机时,我们可以不区分大小写//在证书中建立指向主机名的套接字.字符串hostName = hostname.trim().toLowerCase(Locale.ENGLISH);//验证提供的第一个CN.其他CN被忽略.Firefox,wget,//curl,Sun Java就是这样工作的.字符串firstCn = getFirstCn(x509);System.out.println(TAG +:firstCn:" + firstCn);如果(matches(hostName,firstCn)){返回true;}对于(String cn:getDNSSubjectAlts(x509)){如果(matches(hostName,cn)){返回true;}}返回false;});返回okHttpClientBuilder.build();}私有静态字符串getFirstCn(X509Certificate cert){字符串subjectPrincipal = cert.getSubjectX500Principal().toString();for(String token:subjectPrincipal.split(,")){int x = token.indexOf("CN =");如果(x> = 0){返回token.substring(x + 3);}}返回null;}私有静态类AddHeaderInterceptor实现了Interceptor {@Override公共响应拦截(@NonNull链链)引发IOException {Request.Builder builder = chain.request().newBuilder();builder.addHeader("X-Requested-With","XMLHttpRequest"));builder.addHeader(授权",SharedHelper.getKey(MvpApplication.getInstance(),"access_token")));Log.d("TTT access_token",SharedHelper.getKey(MvpApplication.getInstance(),"access_token")));return chain.proceed(builder.build());}}
有人可以建议我可以在Play商店上发布发布之前检查是否存在漏洞,也可以通过任何方式绕过此问题吗?
下面是项目内部HostnameVerifier的实现.
我在发布前的报告中收到了17条警告.其中一些是由于okhttp.这是警告之一.
StrictMode策略违规:android.os.strictmode.NonSdkApiUsedViolation:Lcom/android/org/conscrypt/OpenSSLSocketImpl;-> setHostname(Ljava/lang/String;)V在android.os.StrictMode.lambda $ static $ 1(StrictMode.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.< init>(AndroidSocketAdapter.kt:36)在okhttp3.internal.platform.android.StandardAndroidSocketAdapter.< init>(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.< init>(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.findPlatform(Platform.kt:212)在okhttp3.internal.platform.Platform $ Companion.access $ findPlatform(Platform.kt:169)在okhttp3.internal.platform.Platform.(Platform.kt:170)在okhttp3.OkHttpClient.< init>(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
I know this is an old topic. But I have tried all the solutions from most answers. I have uploaded the App 10 times in 2 days and kept on having the same notification from Google Play Support.
When I have had the notification sent from Google, I was using the built in Hostname Verifier of okhttp3. But after having multiple failures I have updated all the dependencies and added a hostname verifier. Still the update have been rejected. Here is my ApiClient class.
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());
}
}
Can someone suggest anyways I can check for possible vulnerability before posting a release on Play Store or any way to bypass this issue?
Following are the implementation of HostnameVerifier inside the project.
I have got 17 warning in Prelaunch report. Some of them are due to okhttp. Here is one of the warnings.
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)
I am using okhttp 4.9.0 and retrofit 2.9.0
Dupe of Google Play Security Alert - Your app is using an unsafe implementation of the HostnameVerifier
Do not write your own HostnameVerifier, you are only making less secure and them less likely to approve. You need to find the implementation of HostnameVerifier that they are flagging and stop using that.
You should also follow the instructions you linked to in the photo https://support.google.com/faqs/answer/7188426?hl=en
Tag this question with android-security and possibly contact them using the form they have provided.
Also edit your question to show the implementations you have in your project
这篇关于Playstore Vulnerablity HostnameVerifier接口的不安全实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!