Skip to content

WebView Exploitation

Abusing the WebView component to execute code, access local files, steal data, or bridge between web and native Android context. WebView is an embedded browser. When misconfigured, it gives web content access to native device capabilities.

Requirements

Requirement Details
Permission None (exploits app misconfiguration)
Condition Target app loads attacker-controlled URLs in a WebView or exposes JavaScript interfaces

Attack Surface

WebView inherits the app's permissions. If the host app has READ_CONTACTS, CAMERA, or INTERNET, JavaScript running in the WebView can potentially access those through exposed interfaces.

Attack Patterns

JavaScript Interface Abuse

Apps expose Java objects to JavaScript via addJavascriptInterface():

webView.addJavascriptInterface(new MyBridge(), "AndroidBridge");

JavaScript in the WebView can call methods on MyBridge:

AndroidBridge.sendSMS("1234567890", "message");

If the app loads attacker-controlled content into this WebView, the attacker's JavaScript calls the exposed methods directly.

Pre-API 17 (Android 4.2): any public method on the interface object was callable, including getClass(). This enabled full arbitrary code execution via reflection:

AndroidBridge.getClass().forName("java.lang.Runtime")
    .getMethod("exec", String.class)
    .invoke(null, "id");

API 17+: only methods annotated with @JavascriptInterface are exposed. This closed the reflection path but exposed methods are still callable.

File Access

WebView file access settings:

Setting Default Risk
setAllowFileAccess(true) true (API < 30), false (API 30+) Load file:// URIs, read local files
setAllowFileAccessFromFileURLs(true) false (API 16+) JavaScript in file:// pages can read other file://
setAllowUniversalAccessFromFileURLs(true) false (API 16+) JavaScript in file:// pages can access any origin
setAllowContentAccess(true) true Load content:// URIs

If an app loads file:///data/data/com.target.app/shared_prefs/config.xml in a WebView with file access enabled, JavaScript can read the content. Combined with XHR, files can be exfiltrated:

var xhr = new XMLHttpRequest();
xhr.open("GET", "file:///data/data/com.target.app/shared_prefs/credentials.xml", false);
xhr.send();
var data = xhr.responseText;

URL Redirection / Content Injection

If the app loads URLs from intent extras or deep link parameters:

String url = getIntent().getStringExtra("url");
webView.loadUrl(url);

An attacker sends an intent with url=https://evil.com/phishing.html, and the WebView loads attacker content within the app's UI context. Users see the app's chrome (toolbar, navigation) around malicious content.

shouldOverrideUrlLoading Bypass

Apps use shouldOverrideUrlLoading() to filter URLs. Common bypass patterns:

  • URL encoding to evade string matching
  • Redirects through allowed domains
  • Fragment identifiers (#) to carry data past filters
  • JavaScript-initiated navigation vs. user-initiated navigation (handled differently)

WebResourceResponse Exploitation

Apps that override shouldInterceptRequest() to serve local content via WebResourceResponse can be exploited for arbitrary file theft. Oversecured documented this attack class using Amazon app vulnerabilities as examples: if the app returns file contents based on URL parameters without path validation, an attacker can request internal files.

public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
    String path = request.getUrl().getPath();
    File file = new File(getFilesDir(), path);
    return new WebResourceResponse("text/html", "utf-8", new FileInputStream(file));
}

A request to https://trusted.domain/../shared_prefs/credentials.xml traverses out of the intended directory. Oversecured's file theft checklist covers systematic identification of these patterns.

loadDataWithBaseURL Abuse

When an app uses loadDataWithBaseURL() with a privileged base URL, any JavaScript in the loaded HTML inherits origin access to that domain:

webView.loadDataWithBaseURL("https://trusted.domain", htmlContent, "text/html", "utf-8", null);

If htmlContent comes from attacker-controlled input, the JavaScript runs in the context of trusted.domain, with access to its cookies and local storage. Oversecured demonstrated this in Evernote, achieving universal XSS and theft of all cookies from all sites by combining exported activity abuse with loadDataWithBaseURL.

WebView shares a cookie store via CookieManager. If an attacker can load content in the same WebView instance used for authenticated sessions, they can access session cookies:

document.cookie; // reads cookies for the current domain

If setAllowUniversalAccessFromFileURLs(true) is set, a file:// page can read cookies for any domain.

Beyond JavaScript-based access, the WebView cookie database file itself (/data/data/com.target.app/app_webview/Cookies) can be stolen through content provider path traversal or file theft chains, providing offline access to all stored cookies without executing JavaScript.

SSL Pinning Bypass via WebView

WebView SSL errors can be overridden:

webView.setWebViewClient(new WebViewClient() {
    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        handler.proceed(); // accepts any certificate
    }
});

This enables MITM attacks on all WebView traffic within the app.

Detection During Analysis

Static Indicators
  • addJavascriptInterface() calls and what methods are exposed
  • setAllowFileAccess(true), setAllowFileAccessFromFileURLs(true), setAllowUniversalAccessFromFileURLs(true)
  • URL loading from untrusted input (intent extras, deep link parameters)
  • onReceivedSslError with handler.proceed()
  • setJavaScriptEnabled(true) combined with any of the above
  • shouldInterceptRequest() overrides returning file contents based on URL parameters
Dynamic Indicators
  • WebView loading URLs from intent extras or deep link parameters
  • JavaScript bridge calls to native methods exposing sensitive functionality
  • File access attempts via file:// or content:// URIs in WebView
  • SSL errors silently accepted during WebView navigation

Oversecured's WebView security checklist provides a systematic approach to auditing WebView configurations. 8kSec's deep link and WebView exploitation guide provides hands-on exploitation walkthroughs using the InsecureShop vulnerable app, covering URL validation bypass techniques (e.g., verifying authority vs. domain name suffix).

Vendor-Specific WebView Vulnerabilities

OEM customizations introduce WebView attack surface beyond AOSP. Oversecured disclosed 7 Android and Pixel vulnerabilities including arbitrary file theft via WebView with default settings on stock Android devices. Their Xiaomi research found 20 security issues in Xiaomi system apps, several involving WebView misconfiguration in vendor-specific components. Oversecured's systematic audit of 225 Google apps revealed widespread WebView issues across Google's own app ecosystem.

Android Mitigations

Version Mitigation Bypass
Android 4.2 (API 17) @JavascriptInterface annotation required; reflection path via getClass() closed Explicitly annotated methods remain callable
Android 4.4 (API 19) Chromium-based WebView replaces Android WebKit; improved sandboxing Application-level misconfigurations still exploitable
Android 7.0 (API 24) setAllowFileAccessFromFileURLs() and setAllowUniversalAccessFromFileURLs() default to false Apps explicitly enabling these settings remain vulnerable
Android 9.0 (API 28) Per-process WebView data directory isolation Does not prevent exploitation within the same process
Android 10 (API 29) setAllowFileAccess() defaults to false for WebViews targeting API 29+ Legacy apps targeting lower API levels still default to true

Families Using This Technique

Banking trojans heavily rely on WebView for overlay attacks. Overlay injects are typically HTML/JavaScript pages loaded in a WebView positioned over the target banking app. The WebView loads HTML/CSS/JS inject templates from C2, styled to match the target app's login screen.

Family WebView Usage Notes
Cerberus Overlay injects 300+ inject templates loaded via WebView
Anubis Overlay injects WebView injects + embedded keylogger
Octo Overlay injects WebView overlays combined with screen streaming
Hook Overlay injects 400+ targets, WebView injects from C2
GodFather Dynamic overlays WebView loads per-target HTML dynamically
Ermac Overlay injects Inherited Cerberus WebView inject system
Hydra Overlay injects 400+ target WebView templates
Xenomorph Overlay injects + ATS WebView inject kits with credential phishing
TsarBot Overlay injects 750+ target inject templates
Antidot Multi-language overlays WebView injects in 18 languages
Harly Invisible WebView Loads subscription pages in hidden WebView, auto-clicks subscription confirmation
Joker Invisible WebView Hidden WebView navigates premium subscription flows
BTMOB RAT Credential phishing WebView-based login phishing

Harly and Joker use an inverted approach: instead of showing WebViews to the user, they run invisible WebViews in the background to complete subscription fraud flows without user interaction.