Webview avoids a security warning from a Google game when implementing onReceivedSslError

I have a link that opens in webview. The problem is that it cannot be opened until I redefine onReceivedSslError as follows:

@Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { handler.proceed(); } 

I get a security warning from a Google game saying:

Security Warning Your application has an unsafe implementation of the WebViewClient.onReceivedSslError handler. In particular, the implementation ignores all SSL certificate verification errors, making your application vulnerable to man-in-the-middle attacks. An attacker can modify the affected WebView content, read the transmitted data (for example, login credentials) and execute code inside the application using JavaScript.

To properly handle the SSL certificate, change your code to call SslErrorHandler.proceed () when the certificate provided by the server meets your expectations and otherwise calls SslErrorHandler.cancel (). An email notification containing the affected applications and classes (s) has been sent to your developer account address.

Please fix this vulnerability as soon as possible and increase the version number of the updated APK. For more information about the SSL error handler, see our documentation in the Developer Help Center. For other technical issues, you can send a message https://www.stackoverflow.com/questions and use the tags "android-security" and "SslErrorHandler". If you use a third-party library that is responsible for this, report it to a third party and work with them to solve this problem.

To make sure that you have updated correctly, download the updated version to the developer console and look back after five hours. If the application has not been updated correctly, a warning appears.

Please note that while these specific problems may not affect every application that uses WebView SSL, it is best to stay up to date with all security patches. Applications with vulnerabilities that expose users to compromise may be considered dangerous products in violation of the Content Policy and section 4.4 of the Software Distribution Agreement.

Please ensure that all published applications comply with the Software Distribution Agreement and Content Policy. If you have questions or concerns, please contact our support team through the Google Play Developer Help Center.

If I delete onReceivedSslError (handler.proceed()) , the page will not open.

In any case, I can open the page in a web browser and avoid the security warning.

+44
android google-play android-webview android-security sslerrorhandler
Mar 17 '16 at 2:43
source share
5 answers

To handle SSL certificate validation correctly, change the code to call SslErrorHandler.proceed () when the certificate presented by the server meets your expectations and calls SslErrorHandler.cancel () otherwise.

As the email onReceivedSslError , onReceivedSslError should process the user, go to the page with the invalid certificate, for example, in the notification dialog box. You do not have to act directly.

For example, I am adding a warning dialog so that the user confirms and it looks like Google no longer displays the warning.




 @Override public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) { final AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(R.string.notification_error_ssl_cert_invalid); builder.setPositiveButton("continue", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { handler.proceed(); } }); builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { handler.cancel(); } }); final AlertDialog dialog = builder.create(); dialog.show(); } 



Explain in detail by e-mail.

In particular, the implementation ignores all SSL error certificate verification, making your application vulnerable to man-in-the-center attacks.

The email states that the default implementation ignored the important SSL security issue. Therefore, we need to process it in our own application that used WebView. Notify the user with an alert dialog box is an easy way.

+85
Mar 22 '16 at 6:53
source share
— -

The fix that works for me is to simply disable the onReceivedSslError function defined in AuthorizationWebViewClient . In this case handler.cancel will be called in case of SSL error. However, it works great with SSL certificates for a single drive. Tested on Android 2.3.7, Android 5.1.

+6
Mar 21 '16 at 13:09
source share

According to Google Security Warning: Insecure implementation of the X509TrustManager interface , Google Play will not support the X509TrustManager from July 11, 2016:

Hi, Google Play Developer,

Your applications, listed at the end of this letter, use an unsafe implementation of the X509TrustManager interface. In particular, the implementation ignores all SSL certificate verification errors when establishing an HTTPS connection with a remote host, thereby making the application vulnerable to man-in-the-middle attacks. An attacker can read transmitted data (such as login credentials) and even data changes are transmitted over an HTTPS connection. If you have more than 20 affected applications in your account, please check the developer console for a complete list.

To handle the SSL certificate correctly, change the code in the checkServerTrusted method of your X509TrustManager user interface to raise either CertificateException or IllegalArgumentException each time the certificate submitted by the server does not meet your expectations. For technical issues, you can send messages to Qaru and use the tags "android-security" and "TrustManager".

Please resolve this issue as soon as possible and increase the version number of the updated APK. Starting May 17, 2016, Google Play will block the publication of any new applications or updates that contain an unsafe implementation of the X509TrustManager interface.

To confirm that you have made the correct changes, send the updated version of your application to the Developer Console and check it in five hours. If the application has not been updated correctly, a warning appears.

Although these specific problems may not affect every application using TrustManager, it is best not to ignore the SSL certificate for validation errors. Applications with vulnerabilities that put users at risk of compromise may be considered dangerous products in violation of the Content Policy and Section 4.4 of the developer's distribution Agreement.

...

+3
Jul 21 '16 at 8:42 on
source share

You can use SslError to display some error information of this certified one, and you can write a type error string in your dialog box.

 @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { final SslErrorHandler handlerFinal; handlerFinal = handler; int mensaje ; switch(error.getPrimaryError()) { case SslError.SSL_DATE_INVALID: mensaje = R.string.notification_error_ssl_date_invalid; break; case SslError.SSL_EXPIRED: mensaje = R.string.notification_error_ssl_expired; break; case SslError.SSL_IDMISMATCH: mensaje = R.string.notification_error_ssl_idmismatch; break; case SslError.SSL_INVALID: mensaje = R.string.notification_error_ssl_invalid; break; case SslError.SSL_NOTYETVALID: mensaje = R.string.notification_error_ssl_not_yet_valid; break; case SslError.SSL_UNTRUSTED: mensaje = R.string.notification_error_ssl_untrusted; break; default: mensaje = R.string.notification_error_ssl_cert_invalid; } AppLogger.e("OnReceivedSslError handel.proceed()"); View.OnClickListener acept = new View.OnClickListener() { @Override public void onClick(View v) { dialog.dismiss(); handlerFinal.proceed(); } }; View.OnClickListener cancel = new View.OnClickListener() { @Override public void onClick(View v) { dialog.dismiss(); handlerFinal.cancel(); } }; View.OnClickListener listeners[] = {cancel, acept}; dialog = UiUtils.showDialog2Buttons(activity, R.string.info, mensaje, R.string.popup_custom_cancelar, R.string.popup_custom_cancelar, listeners); } 
+1
Jul 19 '16 at 8:03
source share

I needed to check our trust store before showing any message to the user, so I did this:

 public class MyWebViewClient extends WebViewClient { private static final String TAG = MyWebViewClient.class.getCanonicalName(); Resources resources; Context context; public MyWebViewClient(Resources resources, Context context){ this.resources = resources; this.context = context; } @Override public void onReceivedSslError(WebView v, final SslErrorHandler handler, SslError er){ // first check certificate with our truststore // if not trusted, show dialog to user // if trusted, proceed try { TrustManagerFactory tmf = TrustManagerUtil.getTrustManagerFactory(resources); for(TrustManager t: tmf.getTrustManagers()){ if (t instanceof X509TrustManager) { X509TrustManager trustManager = (X509TrustManager) t; Bundle bundle = SslCertificate.saveState(er.getCertificate()); X509Certificate x509Certificate; byte[] bytes = bundle.getByteArray("x509-certificate"); if (bytes == null) { x509Certificate = null; } else { CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); Certificate cert = certFactory.generateCertificate(new ByteArrayInputStream(bytes)); x509Certificate = (X509Certificate) cert; } X509Certificate[] x509Certificates = new X509Certificate[1]; x509Certificates[0] = x509Certificate; trustManager.checkServerTrusted(x509Certificates, "ECDH_RSA"); } } Log.d(TAG, "Certificate from " + er.getUrl() + " is trusted."); handler.proceed(); }catch(Exception e){ Log.d(TAG, "Failed to access " + er.getUrl() + ". Error: " + er.getPrimaryError()); final AlertDialog.Builder builder = new AlertDialog.Builder(context); String message = "SSL Certificate error."; switch (er.getPrimaryError()) { case SslError.SSL_UNTRUSTED: message = "O certificado não é confiável."; break; case SslError.SSL_EXPIRED: message = "O certificado expirou."; break; case SslError.SSL_IDMISMATCH: message = "Hostname inválido para o certificado."; break; case SslError.SSL_NOTYETVALID: message = "O certificado é inválido."; break; } message += " Deseja continuar mesmo assim?"; builder.setTitle("Erro"); builder.setMessage(message); builder.setPositiveButton("Sim", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { handler.proceed(); } }); builder.setNegativeButton("Não", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { handler.cancel(); } }); final AlertDialog dialog = builder.create(); dialog.show(); } } } 
+1
Oct 18 '17 at 14:19
source share



All Articles