WebView security issues in Android applications

WebView is in common use in Android applications. Although default configuration is secure, developers tend to introduce changes in its configuration which may introduce security risks.
Here you will find tips on how to use WebView with security in mind.

Łukasz Bobrek 2021.10.20   –   6 MIN read

TL;DR

  • Do not enable Javascript support or local file access unless necessary.
  • Enforce HTTPS for all the communication, including Webview.
  • Keep in mind that additional certificate pinning configuration may be required specifically for WebView. 
  • Avoid using JavascriptInterface. If it is required, code very carefully. 
  • Enable Safe Browsing.
  • Disable metrics output for high risk applications.
  • Remember to clear cache, cookies and Local Storage on user logout or application termination.
  • Stay up to date with best security practices while developing mobile apps. See our Guidelines on mobile application security – Android edition

Introduction

WebView is a simple, yet quite powerful way to deliver web-based content across different platforms, including Android. It was first released as a part of Android 4.4 and it embeds browser applications into native APK. Since Android 5.0, Webview is included as a system application. The goal is to deliver critical fixes to the users quickly, which is definitely a plus: 

From my experience, there are three main reasons why companies decide to directly (or indirectly) use WebView in their mobile applications:

  1. Nowadays it is quite common to use hybrid frameworks, like Cordova or PhoneGap to build mobile applications. Those frameworks wrap HTML/Javascript applications into the native Android container and use WebView to make it work.
    Note: Google’s Flutter is the only hybrid framework which does not use WebView, it relies on its own C++ based engine. 
  2. Second reason to use WebView is to present content which may change a lot, for instance terms and conditions in banking applications. It is far easier to modify them just once and then all platforms get the same data. 
  3. Another usage scenario may occur in companies with little or no budget for mobile application development. If you have a web application, you can  very easily build a mobile application, which would only render web content using WebView. 

From the security perspective, WebView may be vulnerable to attacks known for web applications, but it also introduces new types of security problems. For instance, if the application has access to contacts and specific conditions are met, known from web applications Cross-Site Scripting vulnerability can be exploited which may result in stealing contacts from victims device.

Thankfully, in modern Android’s default configuration of WebView is quite strict and as long as developers do not disable security features, most attacks are mitigated. Below, I will cover the most important security settings and try to convince you to not disable them. Finally, I will show you several additional WebView features which increase its security. 

Webview security defaults on Android

Disabled Javascript

By default, Javascript on Android’s Webview is not enabled. Unless necessary, please leave this setting unchanged. 

WebSettings webSettings = securingbiz.getSettings();
webSettings.setJavaScriptEnabled(false);

Enabling javascript makes the application vulnerable to Cross-Site Scripting attacks, which may be the result of improper user-input handling or trusting external sources which always might get compromised. 

On the other hand,Javascript is essential for modern web applications and applications built on  hybrid frameworks. If you need to enable it, remember to properly sanitize untrusted (user-based) input. It is also a good practice to  verify included scripts integrity with the integrity flag: 

<script src="https://example.com/example-framework.js" integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC" crossorigin="anonymous"></script>

Enforced HTTPS

Android 8.0 also enforced HTTPS for all the applications, unless explicitly disabled. 

This, of course, applies also to Webview. More details regarding the subject can be found in the separate chapter:  Force your Android to communicate securely

It is also worth mentioning that WebView may require dedicated implementation of certificate pinning mechanism. 

Disabled access to resources

In case of defaults for access to resources, the situation gets a bit complicated. Different access types have different defaults for different Android versions. In general, we have 4 types of accesses: 

  • Access to content providers (setAllowContentAccess) – this is set to true by default in all the Android versions. Content URL access allows WebView to load content from a content provider installed in the system. 
  • Access to local files (setAllowFileAccess) – On Android 11 it is set to false, but on the lower versions, the default setting is true. This access allows Webview to read all the files that the application has access to. Usually, it is not required, so it is a good practice to manually set this setting to false: 
WebSettings webSettings = securingbiz.getSettings();
webSettings.setAllowFileAccess(false);
  • Of course, even when set to false, Webview can still access /data/data/com.package.name/app_webview folder, which stores webview related data, like LocalStorage.
  • Access to local files from external sources (setAllowFileAccessFromFileURLs and setAllowUniversalAccessFromFileURLs) – Those two settings are potentially very dangerous and since Android Ice Cream Sandwich (ancient times) is disabled by default. Do not enable them! 

Disabled JavascriptInterface

Javascript interface allows Javascript rendered in WebView to run native Java code implemented in the app. This is quite a powerful feature and allows WebView to interact with all device features, like camera, microphone, contacts etc. By default, this is disabled, BUT hybrid frameworks, like Cordova, need it enabled to work properly. Please keep this in mind if you use those frameworks or you need to enable this feature. 

Since API 17, it is also required to declare @JavascpitInterface annotation to any Java method which needs to be called from Javascript: 

public class WebAppInterface {
   Context mContext;
 
   /** Instantiate the interface and set the context */
   WebAppInterface(Context c) {
       mContext = c;
   }
 
   /** Show a toast from the web page */
   @JavascriptInterface
   public void showToast(String toast) {
       Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
   }
}

Then, it is required to create an Interface that will be recognized by Javascript, in the case presented below, this interface is called “Android”.

WebView webView = (WebView) findViewById(R.id.webview);
webView.addJavascriptInterface(new WebAppInterface(this), "Android");

Finally, to execute native code the Interface needs to be called from Javascript: 

<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" />
 
<script type="text/javascript">
       function showAndroidToast(toast) {
       Android.showToast(toast);
       }
</script>

Enable Safe Browsing

Google’s Safe Browsing is a tool that constantly monitors and analyzes websites in terms of security. When a website is marked as malicious, insecure or compromised, Safe Browsing will present suitable warning:

By default, Safe Browsing is disabled for Webview. To enable it, just add the below-mentioned metadata in the application tag of Android Manifest: 

<meta-data android:name="android.webkit.WebView.EnableSafeBrowsing"
   android:value="true" />

Disable metrics collection

For high-risk applications, it is a good practice to disable metrics collection by Google.
It might be a surprise, but if the user agreed to anonymous data collection during Android setup, WebView ran within your application will send data to Google, which looks as presented below

POST /j/collect?v=1&_v=j87&a=1029131340&t=pageview&_s=1&dl=https%3A%2F%2Fsecuring.biz%2F&ul=pl-pl&de=UTF-8&dt=Securing%20-%20more%20than%20security%20testing&sd=24-bit&sr=412x732&vp=412x660&je=0&_u=IEBAAEABAAAAAC~&jid=1340202418&gjid=698478774&cid=977628648.1606484116&tid=UA-12350892-1&_gid=554573850.1606484116&_r=1&_slc=1&z=401775747 HTTP/1.1
Host: www.google-analytics.com
Connection: close
Content-Length: 0
(...)

To disable metrics collection, add the following metadata in the application tag of Android Manifest: 

<meta-data android:name="android.webkit.WebView.MetricsOptOut"
       android:value="true" />

Clear cache and SessionStorage on logout

As mentioned before, WebView is a web browser embedded into the application, which means it uses the same mechanisms as a regular browser. In particular, it could use cache, cookies and store sensitive data in LocalStorage. It is a good security practice to minimize user-related data locally on the device, thus all such data must be cleared on application termination or user logout. To achieve that, the following methods should be called:  

WebStorage.getInstance().deleteAllData();
CookieManager.getInstance().removeAllCookies(null);
CookieManager.getInstance().flush();

Proces separation on Android

It is also worth mentioning that Android 8.0 introduced a new security feature for WebView. Since this release, WebView is rendered in an isolated process, separate from the host app. This solution protects host applications from potential WebView crashes or low-level exploits. Furthermore, the WebView rendering process runs in a restricted sandbox. It cannot on its own write any data in Android memory nor connect to the network on its own

Summary

Using WebView in native Android applications may be a fairly legitimate choice for many developers. For those who decide to use it, keep in mind that it introduced several new risks for mobile applications, also well-known risks for web applications need to be mitigated. The good news is that modern Androids have very strict default settings for WebView. Just sticking to those defaults and implementing a few additional security mechanisms should properly secure WebView usage. But in case of modification of default settings, like enabling Javascript support or using JavascriptInterfaces should be done very thoroughly and additional security mechanisms should be taken into consideration.

In android application development (or any other), it’s also crucial to follow current best practices. We’ve created a useful guide that brings together all of our android security knowledge in one place. Just click on the cover below.

If you have any questions about this article feel free to reach out to me on Twitter or LinkedIn.

Łukasz Bobrek
Łukasz Bobrek Principal IT Security Consultant
Head of Cloud Security