A native bridge lets web content in a WebView call app code. On Android's addJavascriptInterface, the injected object is available to every frame, and the app cannot verify which frame is calling. Keep bridges tiny, load only content you own over HTTPS, and remove the bridge before showing anything else.
Why this matters for cross-platform apps
Many cross-platform and hybrid stacks use a WebView and a bridge: a framework plugin system, a login page inside the app, an embedded help center. Whenever a web page can reach native functions, any script that runs in that page can reach them too.
Android's guidance describes the problem. The injected object is exposed to every frame, including iframes, and there is no mechanism for the app to verify the origin of the calling frame. A malicious frame in an otherwise legitimate page can call the bridge. The result can be code execution with the app's permissions.
Message channels are not automatically safe
The same guidance covers web message ports. Without origin checks on the endpoints, messages can be accepted from any sender. Specify the expected sending domain, and avoid a wildcard target origin.
Mitigations
Android's documentation lists these, and they carry over to any framework that wraps a WebView.
- Disable JavaScript where you show static content.
- Remove the interface before loading untrusted content.
- Load content only over HTTPS, and set cleartext traffic to false in the manifest.
- Allowlist scheme and host. Open any other domain in the default browser.
- Load only content you own, with strictly scoped URLs.
- Do not expose sensitive data or operations through a bridge. Start sensitive actions from native code, with clear disclosure to the user.
- Call the interface API only on API level 21 or higher.
In addition, validate every argument that arrives through a bridge method on the native side and expose as few methods as possible, each annotated for exposure.
A review routine
Search your code and your plugins for bridge registration. For each one, write down which pages can load in that WebView, what each method does, and what the worst argument could do. If a page can load third party content, such as ads or a rich text widget, give it a separate WebView with no bridge.
Also check redirects. An allowlisted page that redirects to another host can end up in the bridge enabled view, so apply the host check to redirects too.
Dependency scanning helps with the plugin side: bridge plugins are code you did not write. Safeguard can scan a project's dependencies and give you an SBOM, and you can try a free scan at https://gold.safeguard.sh/scan.
Try it yourself
Click through it at your own pace, or open it full screen.
Run the code scan and look at how findings point to the exact line, the same way you should find every bridge registration.
Quick check
Is it fine to bridge if I only ever load my own domain?
It is much safer, but an XSS bug on that domain then reaches native code. Keep methods minimal and validate input, so a page bug does not become an app compromise.
Sources
Last reviewed: 19 October 2026.