[GH-ISSUE #3518] [Feature] Model the Cordova/Capacitor WebView bridge in JavaScript and Android analysis #1309

Open
opened 2026-10-16 21:04:05 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @Rinkia on GitHub (Oct 14, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/3518

Before submitting

  • I searched the open and closed issues and pull requests for a related proposal (Cordova, Capacitor, Ionic, WebView bridge, addJavascriptInterface: nothing related; #2834 is the nearest JavaScript-analysis report).
  • I understand the contribution scope must be reviewed before integration; open questions are welcome here.
  • This request does not include credentials, private samples, or sensitive target data.

Area

Evidence, artifacts, or reconstruction

Current limitation

Many Android apps are hybrids: a WebView runs a web app (Cordova, Ionic, Capacitor) and calls native code through a bridge. REA already models the equivalent boundary for Electron (preloads, context-bridge APIs, IPC with literal vs dynamic channels, renderer and main pairing). For hybrid Android apps the boundary isn't modelled, so the result reports zero on every boundary field even when the bridge is the most important part of the app.

Observed on a real app (a Play Store build, so private; aggregate numbers only):

  • analyze-javascript-application on the extracted assets/www (Ionic/AngularJS, 4,836 files) worked well: 402 JS files parsed, about 1.12M AST nodes, 0 parse failures, about 50 s. The summary is Electron-shaped (browser_windows, preload_entrypoints, context_bridge_apis, ipc.*, native_addon_bindings), and every field is 0.
  • The app's actual bridge: 99 cordova.exec(success, error, service, action, args) call sites in app code. 87 target one custom service; the rest go to SQLitePlugin, Insomnia and Share. For the custom service, only 9 distinct action names are string literals at the call site; the rest are passed through variables. That's the same literal vs dynamic split REA already reports for Electron IPC channels.
  • Android side: the service → class mapping lives in res/xml/config.xml, which is hard to reach when resource names are obfuscated. I found the implementation by tracing org.apache.cordova.CordovaPlugin with trace-android-references (58 references, coverage: complete): one CordovaPlugin.execute(String action, JSONArray, CallbackContext) that dispatches to five handler scopes. Native-to-JS calls also exist: a native "event sink" class pushes map taps back into the page.

Pairing the JS operations with that execute implementation took manual grep plus several REA calls. The pieces exist in REA, but there's no bridge result.

Use cases

  • Hybrid Android apps (Cordova/Ionic/Capacitor) and plain WebView.addJavascriptInterface bridges: find every JS → native operation and the class that handles it.
  • Security review: list which native capabilities (location, file system, auth secrets, billing) the web layer can reach, and which calls use dynamic action names.
  • Migration analysis (web layer to native UI, as in the app above): which bridge actions still exist and where.

Desired outcome and success criteria

  • JavaScript analysis reports cordova.exec (and Capacitor Plugins.X.method) operations, each with service, action, literal vs dynamic, and source location, like the IPC section does for Electron.
  • Android analysis reports bridge implementations: CordovaPlugin subclasses with their execute entry points, the service names from config.xml when decodable, and addJavascriptInterface objects with their @JavascriptInterface methods.
  • A pairing view: JS service/action ↔ native class (paired / unpaired / dynamic), labelled as a static association rather than an observed call.
  • Success: on a Cordova sample, literal operations pair with their plugin class; dynamic ones are counted and located rather than dropped.

Expected interaction with targets

Read existing files or captured data.

Verification available so far

I can suggest a sample or manual check.

Verification details

The figures above come from rea-agents 6.4.0/6.5.0 in the Docker image (extract-artifact, analyze-javascript-application, search-android-classes, trace-android-references, inspect-android-class). The sample isn't shareable. Any open-source Cordova or Ionic app would reproduce the shape, and I can look for a public F-Droid/GitHub sample if that helps.

Alternatives considered

  • Treating cordova.exec as Electron IPC. The shapes differ (a service/action pair, not a channel; the native side is a JVM class, not a main-process handler), so a dedicated hybrid-bridge section seems clearer.
  • Manual grep plus trace-android-references. That's what I did; it works, but it isn't Evidence and doesn't classify dynamic actions.

Possible direction

  • JS side: a syntax pattern for cordova.exec(…, "<service>", "<action>", …) and exec wrappers, reusing the literal and dynamic classification from the IPC analysis.
  • Android side: the class hierarchy check for org.apache.cordova.CordovaPlugin, plus addJavascriptInterface call sites. JADX already exposes both.
  • Pairing could use the same static-binding labels discussed in #2379.

References

  • Electron IPC and context-bridge modelling in docs/javascript-application-workflows.md / docs/electron-observation.md
  • #2379 (JNI correlation, static vs observed labels), #2834
Originally created by @Rinkia on GitHub (Oct 14, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/3518 ### Before submitting - [x] I searched the open and closed issues and pull requests for a related proposal (Cordova, Capacitor, Ionic, WebView bridge, addJavascriptInterface: nothing related; #2834 is the nearest JavaScript-analysis report). - [x] I understand the contribution scope must be reviewed before integration; open questions are welcome here. - [x] This request does not include credentials, private samples, or sensitive target data. ### Area Evidence, artifacts, or reconstruction ### Current limitation Many Android apps are hybrids: a WebView runs a web app (Cordova, Ionic, Capacitor) and calls native code through a bridge. REA already models the equivalent boundary for Electron (preloads, context-bridge APIs, IPC with literal vs dynamic channels, renderer and main pairing). For hybrid Android apps the boundary isn't modelled, so the result reports zero on every boundary field even when the bridge is the most important part of the app. Observed on a real app (a Play Store build, so private; aggregate numbers only): - `analyze-javascript-application` on the extracted `assets/www` (Ionic/AngularJS, 4,836 files) worked well: 402 JS files parsed, about 1.12M AST nodes, 0 parse failures, about 50 s. The `summary` is Electron-shaped (`browser_windows`, `preload_entrypoints`, `context_bridge_apis`, `ipc.*`, `native_addon_bindings`), and every field is 0. - The app's actual bridge: 99 `cordova.exec(success, error, service, action, args)` call sites in app code. 87 target one custom service; the rest go to `SQLitePlugin`, `Insomnia` and `Share`. For the custom service, only 9 distinct action names are string literals at the call site; the rest are passed through variables. That's the same literal vs dynamic split REA already reports for Electron IPC channels. - Android side: the service → class mapping lives in `res/xml/config.xml`, which is hard to reach when resource names are obfuscated. I found the implementation by tracing `org.apache.cordova.CordovaPlugin` with `trace-android-references` (58 references, `coverage: complete`): one `CordovaPlugin.execute(String action, JSONArray, CallbackContext)` that dispatches to five handler scopes. Native-to-JS calls also exist: a native "event sink" class pushes map taps back into the page. Pairing the JS operations with that `execute` implementation took manual grep plus several REA calls. The pieces exist in REA, but there's no bridge result. ### Use cases - Hybrid Android apps (Cordova/Ionic/Capacitor) and plain `WebView.addJavascriptInterface` bridges: find every JS → native operation and the class that handles it. - Security review: list which native capabilities (location, file system, auth secrets, billing) the web layer can reach, and which calls use dynamic action names. - Migration analysis (web layer to native UI, as in the app above): which bridge actions still exist and where. ### Desired outcome and success criteria - JavaScript analysis reports `cordova.exec` (and Capacitor `Plugins.X.method`) operations, each with service, action, literal vs dynamic, and source location, like the IPC section does for Electron. - Android analysis reports bridge implementations: `CordovaPlugin` subclasses with their `execute` entry points, the service names from `config.xml` when decodable, and `addJavascriptInterface` objects with their `@JavascriptInterface` methods. - A pairing view: JS service/action ↔ native class (paired / unpaired / dynamic), labelled as a static association rather than an observed call. - Success: on a Cordova sample, literal operations pair with their plugin class; dynamic ones are counted and located rather than dropped. ### Expected interaction with targets Read existing files or captured data. ### Verification available so far I can suggest a sample or manual check. ### Verification details The figures above come from `rea-agents` 6.4.0/6.5.0 in the Docker image (`extract-artifact`, `analyze-javascript-application`, `search-android-classes`, `trace-android-references`, `inspect-android-class`). The sample isn't shareable. Any open-source Cordova or Ionic app would reproduce the shape, and I can look for a public F-Droid/GitHub sample if that helps. ### Alternatives considered - Treating `cordova.exec` as Electron IPC. The shapes differ (a service/action pair, not a channel; the native side is a JVM class, not a main-process handler), so a dedicated hybrid-bridge section seems clearer. - Manual grep plus `trace-android-references`. That's what I did; it works, but it isn't Evidence and doesn't classify dynamic actions. ### Possible direction - JS side: a syntax pattern for `cordova.exec(…, "<service>", "<action>", …)` and `exec` wrappers, reusing the literal and dynamic classification from the IPC analysis. - Android side: the class hierarchy check for `org.apache.cordova.CordovaPlugin`, plus `addJavascriptInterface` call sites. JADX already exposes both. - Pairing could use the same static-binding labels discussed in #2379. ### References - Electron IPC and context-bridge modelling in `docs/javascript-application-workflows.md` / `docs/electron-observation.md` - #2379 (JNI correlation, static vs observed labels), #2834
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#1309
No description provided.