flawopen.com/Android WebView security/addJavascriptInterface
Android addJavascriptInterface: security risks and safe use
Treat a WebView with addJavascriptInterface as a privileged boundary. Android injects the object into every frame and cannot tell your app which frame called it. If attacker-controlled JavaScript reaches any frame, it may invoke exposed bridge methods with the app's permissions. Keep bridged WebViews limited to app-controlled content, and load untrusted pages in a separate WebView without the bridge.
Why the bridge changes the XSS impact
A bridge gives JavaScript callable entry points into the host app. Android exposes the object to every frame, including iframes, and provides no calling-frame origin check for addJavascriptInterface. A script injected into a page or frame can therefore reach annotated bridge methods; what it can do next is bounded by those methods and the app's own authorization checks. On apps targeting API 16 or earlier, Android documents a more severe legacy behavior: all public methods may be exposed. API 17+ requires @JavascriptInterface, but that annotation does not make untrusted content safe.
Keep the bridge away from untrusted pages
webView.addJavascriptInterface( NativeBridge(), "Android" ) webView.loadUrl(untrustedUrl)
// This WebView is reserved for packaged, app-controlled UI. trustedWebView.settings.javaScriptEnabled = true trustedWebView.addJavascriptInterface( NativeBridge(), "Android" ) trustedWebView.loadUrl("file:///android_asset/index.html") // A different WebView handles remote or user-controlled pages. untrustedWebView.removeJavascriptInterface("Android") untrustedWebView.settings.javaScriptEnabled = false // Validate HTTPS and an explicit host allowlist. untrustedWebView.loadUrl(validatedHttpsUrl)
The strongest boundary is architectural: never navigate a bridge-enabled WebView to a remote, user-generated, or otherwise attacker-influenced page. If navigation to untrusted content is unavoidable, remove the interface before loading it and use a separate WebView with JavaScript disabled unless required. Android notes that the injected object is available to all frames and that removal takes effect after the next page load. HTTPS protects transport; it does not make a host or its content trusted. Validate both URL scheme and host, and open out-of-scope links in the system browser. Keep bridge methods narrow, validate every argument, and enforce user authorization in native code rather than trusting the calling page.
Android WebView bridge security FAQ
No. API 17+ limits exposure to public methods annotated with @JavascriptInterface; it does not add a caller-frame origin check or make attacker-controlled content trustworthy. Keep the bridge on a WebView that only loads content your app controls.
References
- Android Developers — WebView native bridge risks and mitigations
- Android Developers — WebView.addJavascriptInterface API reference
- Android Developers — JavascriptInterface API reference