我更新了应用的版本代码和版本名称,但我收到了来自Google Play的警告消息
您的应用正在使用HostnameVerifier接口的不安全实现。您可以在此Google帮助中心文章中找到有关如何解决问题的详细信息。
提前致谢
答案 0 :(得分:2)
有很多我们认为在这个 Flutter 项目 中是正确的版本,但一次又一次地被拒绝,但最终,我们想通了。
Pubspec.yaml - 以前的版本。
flutter_html: ^0.11.1
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
http: ^0.12.0+2
provider: ^4.1.3
logger: ^0.7.0+2
shared_preferences: ^0.5.4+6
json_annotation: ^3.0.0
flutter_dotenv: ^2.1.0
flutter_swiper: ^1.1.6
package_info: ^0.4.0+3
get_version: ^0.2.0+1
uuid: ^2.0.4
flappy_translator: ^1.2.2
flutter_circular_chart: ^0.1.0
percent_indicator: "^2.1.1"
intl: ^0.16.0
bezier_chart: ^1.0.15
charts_flutter: ^0.8.1
fl_chart: ^0.6.0
flutter_native_timezone: ^1.0.4
url_launcher: ^5.7.8
permission_handler: ^5.0.1+1
onesignal_flutter: 2.6.1
flutter_braintree: 1.1.0
after_layout: ^1.0.7+2
flutter_svg: ^0.19.0
custom_switch_button: 0.5.0
wc_flutter_share: ^0.2.2
esys_flutter_share: ^1.0.2
just_audio: ^0.4.4
cached_network_image: 2.2.0+1
sqflite: ^1.3.1
cupertino_icons: ^0.1.2
in_app_purchase: 0.3.4+5
主机名验证
HttpsURLConnection.setDefaultHostnameVerifier { hostname, arg1 ->
val herokuPattern = “PROJECTNAME-(dev|stg|prd)\\.herokuapp.com”.toRegex()
val awsPattern = “PROJECTNAME-(dev|stg|prd)\\.s3\\..*\\.amazonaws.com”.toRegex()
herokuPattern.containsMatchIn(hostname)
|| awsPattern.containsMatchIn(hostname)
|| hostname.equals(“onesignal.com”, ignoreCase = true)
|| hostname.equals(“api.braintreegateway.com”, ignoreCase = true)
|| hostname.equals(“payments.braintree-api.com”, ignoreCase = true)
|| hostname.equals(“api.sandbox.braintreegateway.com”, ignoreCase = true)
|| hostname.equals(“payments.sandbox.braintree-api.com”, ignoreCase = true) }
在第一次尝试后,我们和您一样收到了这条消息:
<块引用>HostnameVerifier您的应用正在使用不安全的实现 HostnameVerifier 接口。你可以找到更多关于 如何解决这篇 Google 帮助中心文章中的问题。
然后我们求助于“Google 开发/开发人员支持”,询问我们应该怎么做,因为缺乏有关该问题的信息。一周后,我们收到了一条消息,并更好地了解了我们如何找到解决方案而不是在哪里可以找到它。
HostnameVerifier 的脆弱实现:
暴露的 Google Cloud Platform (GCP) API 密钥。
OneSignal 相关信息非常清楚,经过短暂搜索后,我们发现了类似的评论,建议将版本号(从 2.6.1 开始)设置为 onesignal_flutter: 2.6.2
。 OneSignal 问题已解决。
说真的,有两个星期的绝望时期,我们找不到任何关于易受攻击的实施问题的东西,也没有“开发者支持”的建议:
<块引用>“虽然我很乐意回答有关管理您的应用程序的任何问题 在 Google Play 商店中,我们的团队没有接受过提供技术支持的培训 支持应用程序开发问题。寻求帮助开发Android 应用程序,我建议使用我们的 Android 开发者网站。该网站有 技术文档、Android SDK 和分发技巧 你的应用程序。” - GooglePlay 开发者支持。
最终,我们不得不处理与我们使用的插件相关的漏洞问题,并发现了一个 Braintree 问题,该问题建议将版本号设置为 flutter_braintree: 1.1.0+1
。
在这两个版本号升级(Onesignal、Braintree)之后,没有更多关于 HostameVerifier 问题的消息,一切似乎都很好。
Pubspec.yaml
flutter_html: ^0.11.1
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
http: ^0.12.0+2
provider: ^4.1.3
logger: ^0.7.0+2
shared_preferences: ^0.5.4+6
json_annotation: ^3.0.0
flutter_dotenv: ^2.1.0
flutter_swiper: ^1.1.6
package_info: ^0.4.0+3
path_provider: 1.6.24
get_version: ^0.2.0+1
uuid: ^2.0.4
flappy_translator: ^1.2.2
flutter_circular_chart: ^0.1.0
percent_indicator: "^2.1.1"
intl: ^0.16.0
bezier_chart: ^1.0.15
charts_flutter: ^0.8.1
fl_chart: ^0.6.0
flutter_native_timezone: ^1.0.4
url_launcher: ^5.7.8
permission_handler: ^5.0.1+1
onesignal_flutter: 2.6.2
flutter_braintree: 1.1.0+1
after_layout: ^1.0.7+2
flutter_svg: ^0.19.0
custom_switch_button: 0.5.0
wc_flutter_share: ^0.2.2
esys_flutter_share: ^1.0.2
just_audio: ^0.5.7
cached_network_image: 2.2.0+1
sqflite: ^1.3.1
cupertino_icons: ^0.1.2
in_app_purchase: 0.3.4+5
答案 1 :(得分:1)
肯定你有一个类似于这个
的代码 HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
return true;
}
};
或者:
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier(){
public boolean verify(String hostname, SSLSession session) {
return true;
}});
替换为:
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
if(myHostNameToVerify==hostname || myOtherHostNameToVerify == hostname) {
return true;
} else {
return false;
}
}
};
或者:
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier(){
public boolean verify(String hostname, SSLSession session) {
if(myHostNameToVerify==hostname ||
myOtherHostNameToVerify == hostname) {
return true;
} else {
return false;
}
}});
如果您使用SSL验证程序,我建议添加与此类似的代码:
@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();
Google从2016年中期到2017年初需要更安全的代码。