【发布时间】:2020-12-12 22:05:24
【问题描述】:
我知道这是一个老话题。但是我已经尝试了大多数答案中的所有解决方案。我在 2 天内上传了该应用程序 10 次,并不断收到来自 Google Play 支持的相同通知。
当我收到 Google 发送的通知时,我使用的是 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 商店发布版本之前检查可能存在的漏洞或以任何方式绕过此问题吗?
以下是项目内部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)
我正在使用 okhttp 4.9.0 和改造 2.9.0
【问题讨论】:
-
也许在您的应用或第三方库中某处有调试实现?
-
我的代码中没有这样的实现。有没有办法知道任何库项目中是否存在漏洞?
-
您是否有可能在构建中包含任何测试源?您能否从您的 IDE 中发布一个屏幕截图,显示此接口在您的应用中的实现?
-
我从谷歌得到的官方回答,要求提供诊断工具,如下所示:“如果您对漏洞有技术问题,可以发布到 Stack Overflow 并使用标签“android-安全。”对此我们束手无策。我们唯一的提示是,它可能与braintree/paypal 库有关。你们使用它吗?github.com/braintree/braintree_android/issues/312
-
我收到回复说贝宝是罪魁祸首。另外,我的一个应用程序已经发布。您的项目中是否有 network_security_config.xml 来过滤主机名?
标签: java android google-play okhttp android-security