OWASP Mobile Application Security Testing Guide: MASTG KNOW 0018

---
masvs_category: MASVS-PLATFORM
platform: android
title: WebViews
---

On Android versions prior to 4.4, WebViews used the WebKit rendering engine to display web pages. Since Android 4.4, [WebViews have been based on Chromium](https://developer.android.com/about/versions/lollipop#WebView), providing improved performance and compatibility. However, the pages are still stripped down to minimal functions; for example, pages don't have address bars.

## URL Loading in WebViews

WebViews are Android's embedded components which allow your app to open web pages within your application. In addition to mobile apps related threats, WebViews may expose your app to common web threats (e.g. XSS, Open Redirect, etc.).

One of the most important things to do when testing WebViews is to make sure that only trusted content can be loaded in it. Any newly loaded page could be potentially malicious, try to exploit any WebView bindings or try to phish the user. Unless you're developing a browser app, usually you'd like to restrict the pages being loaded to the domain of your app. A good practice is to prevent the user from even having the chance to input any URLs inside WebViews (which is the default on Android) nor navigate outside the trusted domains. Even when navigating on trusted domains there's still the risk that the user might encounter and click on other links to untrustworthy content (e.g. if the page allows for other users to post comments). In addition, some developers might even override some default behavior which can be potentially dangerous for the user.

## SafeBrowsing API

To provide a safer web browsing experience, Android 8.1 (API level 27) introduces the [`SafeBrowsing API`](https://developers.google.com/safe-browsing/v4), which allows your application to detect URLs that Google has classified as a known threat.

By default, WebViews show a warning to users about the security risk with the option to load the URL or stop the page from loading. With the SafeBrowsing API you can customize your application's behavior by either reporting the threat to SafeBrowsing or performing a particular action such as returning back to safety each time it encounters a known threat. Please check the [Android Developers documentation](https://developer.android.com/about/versions/oreo/android-8.1#safebrowsing) for usage examples.

You can use the SafeBrowsing API independently from WebViews using the [SafetyNet library](https://developer.android.com/training/safetynet/safebrowsing), which implements a client for Safe Browsing Network Protocol v4. SafetyNet allows you to analyze all the URLs that your app is supposed to load. You can check URLs with different schemes (e.g. http, file) since SafeBrowsing is agnostic to URL schemes, and against `TYPE_POTENTIALLY_HARMFUL_APPLICATION` and `TYPE_SOCIAL_ENGINEERING` threat types.

> When sending URLs or files to be checked for known threats make sure they don't contain sensitive data which could compromise a user's privacy, or expose sensitive content from your application.

## Virus Total API

Virus Total provides an API for analyzing URLs and local files for known threats. The API Reference is available on [Virus Total developers page](https://developers.virustotal.com/reference#getting-started "Getting Started").

## JavaScript Execution in WebViews

JavaScript can be injected into web applications via reflected, stored, or DOM-based Cross-Site Scripting (XSS). Mobile apps are executed in a sandboxed environment and don't have this vulnerability when implemented natively. Nevertheless, WebViews may be part of a native app to allow web page viewing.

Android WebViews can use [`setJavaScriptEnabled`](https://developer.android.com/reference/android/webkit/WebSettings#setJavaScriptEnabled(boolean)) to enable JavaScript execution. This feature is disabled by default. When enabled, JavaScript code executes in the context of the loaded page, including any scripts provided by that content.

## WebView-Native bridges

Android provides multiple mechanisms for communication between web content in a `WebView` and native app code, which differ in their design, capabilities, and security properties. Some are based on asynchronous message passing, while others use a synchronous injected object model.

For additional platform details, see Android's documentation on ["Access native APIs with JavaScript bridge"](https://developer.android.com/develop/ui/views/layout/webapps/native-api-access-jsbridge) and ["WebView – Native bridges"](https://developer.android.com/privacy-and-security/risks/insecure-webview-native-bridges).

### `addWebMessageListener`

[`addWebMessageListener`](https://developer.android.com/develop/ui/views/layout/webapps/native-api-access-jsbridge) is a message based bridge API provided through AndroidX WebKit. Android describes it as the most modern and recommended approach for communication between web content and native app code. The app registers a listener object name, such as `myObject`, together with a set of `allowedOriginRules`. Matching pages receive an injected JavaScript proxy object that can exchange messages with the app asynchronously. The callback also provides metadata such as the sender origin, whether the message came from the main frame, and a reply proxy for sending a response.

Android documents this mechanism as allowlist-based. The injected object is exposed only to origins that match the configured origin rules, and the same mechanism can work across matching frames. The native side typically uses `WebViewCompat.addWebMessageListener(...)`, and the JavaScript side communicates through the injected proxy object's `postMessage` and `onmessage` APIs.

### `postWebMessage`

[`postWebMessage`](https://developer.android.com/develop/ui/views/layout/webapps/native-api-access-jsbridge) is an asynchronous messaging API that Android documents as an alternative similar to the web platform's `window.postMessage`. The app sends a payload to the web page's main frame with `WebViewCompat.postWebMessage(...)`. For bidirectional communication, the app can create a `WebMessageChannel` and transfer one of its ports to the page. Android characterizes this mechanism as origin aware and notes that it is limited to the main frame. The documentation also notes URI related constraints for content loaded with `data:`, `file:`, or `loadData()` unless `*` is used as the target origin.

### `addJavascriptInterface`

[`addJavascriptInterface`](https://developer.android.com/develop/ui/views/layout/webapps/native-api-access-jsbridge#addjavascriptinterface) is the oldest bridge mechanism. Android describes it as a synchronous legacy model. The app creates a Java or Kotlin object, annotates exposed methods with [`@JavascriptInterface`](https://developer.android.com/reference/kotlin/android/webkit/JavascriptInterface), and injects the object into the `WebView` with `addJavascriptInterface(Object, String)`. JavaScript can then call the exposed methods