3 min to read
Can Android Be XSSed? Account Takeover via JavaScript Bridge
Account Takeover through XSS on websites is nothing new. But does the same attack vector exist on Android?
When people hear XSS, they usually think of browsers and websites. Android apps rarely come to mind.
In reality, any environment that renders HTML and executes JavaScript can be affected including Android WebViews (yes, an Android app, not a browser).
Okay, before we dive into how the flow works, let’s first talk about what actually happens.
Story
This was one of the most complex findings we came across in Q3 (myself, @lamsyah, and @fariqfgi). It ended up being quite involved, as it required bringing together two approaches (Dynamic Testing and Static Analysis).
The primary impact of this finding is Account Takeover, which could allow an attacker to gain full control over a victim’s account.
The Signal
As context, before we explored XSS on Android, @lamsyah had already discovered an unauthenticated XSS on https://subdomain.target.com (a domain explicitly trusted by the target APK).

Instead of stopping there, we pushed the analysis further.
In this case, we observed the following conditions in the APK:
- The target is an Android application that uses a WebView
- A deep link is implemented and passes a URL parameter directly into loadUrl
- JavaScript is enabled within the WebView
- The application exposes native functionality to JavaScript via addJavascriptInterface
XSS Payload
What do you think if I drop this?

From what you can see, this deep link directly loads an external website. What makes this interesting is that the deep link is not fully open, it only allows domains under “target.com”.
What is inside https://subdomain.target.com/xssed-page?

As we can see, the page where we injected the XSS payload looks roughly like the screenshot above. Instead of accessing document.cookie (as usual), we’re calling window.CustomJSBridge.
- Is window.CustomJSBridge something common? Definitely not.
- So how did you discover it? Let’s dig deeper.
Static Analysis (APK)
Before crafting the XSS payload, we first needed to perform reverse engineering on the APK. Yes, the most boring part, opening JADX (Dex to Java Decompiler).
The following snippet shows the class used by the deep link.

What does addJavascriptInterface do?
It exposes native Android methods to JavaScript, allowing web content loaded in a WebView to directly call native code.
Next, we need to see what “methods” are implemented in CustomJSBridge.

What caught our attention is the withCredential() method, which retrieves the token from Android storage to use when opening the WebView.
At this point, we already knew what needed to be called. The XSS payload wasn’t something random, it followed what already existed in the APK.
Execution
After all the analysis is done, it’s time to execute.


For learning purposes, this isn’t a 100% real PoC, just a simulated setup.
And boom!


Summary
XSS doesn’t stop at the browser.
Once an Android application renders HTML, enables JavaScript, and exposes native methods through addJavascriptInterface, it becomes part of the web threat model (whether developers realize it or not).
In this case, a trusted subdomain, a permissive deep link, and an exposed native bridge were enough to turn a simple XSS into an Account Takeover scenario.
Comments