Full Report
The author of this post was reverse-engineering a mobile application for weird handling of deeplinks. While doing this, they found a Browsable intent-filter with a custom Schema. Additionally, the app had a WebView with no host restrictions and a NativeMessage handler that uses postMessage. Altogether, this functionality created a large attack surface to explore, so they decided to dig in. The NativeMessageHandler() JSInterface (webview to native) only had a single exported message: postMessage. It had two types of actions: Native and Standard. After registering yourself as a sender, there were actions like sharing/saving files and more. This code contained an arbitrary file write via a path traversal. Classic! The author began to ask themselves was the consequence of this was though. The application they were testing used React Over the Air updates to allow for updating JavaScript bundles without going through the app store for review. After playing around with these directories, they found the right information to write to gain RCE on the Android device after an app crash. The deeplink didn't work for ALL URLs; it had a server-side check that verifies whether an endpoint is trusted or not. One of the trusted domains was google.com and its subdomains. Google has a subdomain called sites.google.com that allows for loading arbitrary webpages through an iframe. From this iframe, it was possible to use postMessage to trigger the bug once again. This is the full exploit path: Route a browser on Android to a deeplink to the application with the special Google site iframe from above. Register the native handler. Overwrite the OTA configuration and creates a malicious React Native bundle. Restart the application. This can be done by crashing the app or waiting for the user to restart. The company runs an AI security company. They were able to replicate the finding of this vulnerability using this tool. This appeared to take some guidance to find though. A very crazy chain of issues that led to a sick RCE. Great post!
Analysis Summary
# Vulnerability: Remote Code Execution via WebView JSInterface and Path Traversal
## CVE Details
- **CVE ID:** Not explicitly assigned (Zero-day research/Bug Bounty disclosure)
- **CVSS Score:** 9.6 (Critical - Estimated)
- **CWE:** CWE-22 (Path Traversal), CWE-749 (Exposed Dangerous Method or Interface)
## Affected Systems
- **Products:** Unnamed Android application (Referred to as "Target App")
- **Versions:** All versions prior to the January 2026 disclosure
- **Configurations:**
- App utilizes a WebView with a registered `JSInterface` (`NativeMessageHandler`).
- App uses React Native with "Over the Air" (OTA) update functionality.
- App possesses a Browsable intent-filter with a custom schema.
## Vulnerability Description
The vulnerability is a complex exploit chain involving three primary flaws:
1. **Insecure JSInterface Exposure:** The app exposes `NativeMessageHandler.postMessage` to any website loaded in the WebView. An attacker can perform a handshake to upgrade their session to "Native" status, unlocking privileged functions.
2. **Validation Bypass via Trusted Subdomain:** While the app performs a server-side check for trusted domains, it includes `google.com`. Attackers can use `sites.google.com` to host an iframe that bypasses this check and interacts with the `postMessage` handler.
3. **Path Traversal in Native Function:** The `shareContent` function (available to "Native" senders) lacks input validation on the `fileName` parameter. This allows an attacker to perform arbitrary file writes using `../` sequences.
## Exploitation
- **Status:** PoC available (Validated in research environment)
- **Complexity:** High (Requires chaining multiple logic flaws and OTA update mechanics)
- **Attack Vector:** Network (Remote via a malicious link)
## Impact
- **Confidentiality:** Total (Ability to exfiltrate account tokens, session cookies, and internal files)
- **Integrity:** Total (Ability to overwrite application logic and configuration files)
- **Availability:** High (Can cause persistent application crashes or replace app functionality)
## Remediation
### Patches
- **Vendor Fix:** The vendor has reportedly patched the `shareContent` function to validate file paths and restricted the `JSInterface` to explicitly allow-listed origins only.
### Workarounds
- Disable the customized schema/deeplink handling if not required.
- Implement strict hostname verification for all URLs loaded within internal WebViews.
- Ensure React Native OTA update directories are marked as read-only for the application's own web processes where possible.
## Detection
- **Indicators of Compromise:**
- Presence of unexpected files in `/data/data/[package_name]/shared_prefs/OTAPrefs.xml`.
- Unusual `index.android.bundle` files located outside of the standard internal assets folder.
- Deeplinks originating from `sites.google.com` referencing internal app schemes.
- **Detection Methods:** Static analysis to identify `addJavascriptInterface` usage and dynamic analysis of file system writes during WebView navigation.
## References
- hxxps[://]djini[.]ai/from-webview-to-remote-code-injection/
- hxxps[://]djini[.]ai/author/lyes/