Exfiltrating data from Android applications via WebView Takeover (Open Redirect)
In this article, I go through the scenarios in which I've been able to exfiltrate data from real Android applications, after detecting a WebView takeover (aka "Open Redirect") vulnerability.
Typically this vulnerability is the result of allowing an external Intent
to control a URI
that is loaded onto a WebView
, declared inside the vulnerable application.
This Intent
can sometimes be triggered via deep link, but more often than not, requires that a malicious application be installed in the victim's device.
Note that this article closely relates to the "Exploiting Deep Links in Android" series, particularly with Part 2.
1. Abusing Javascript Bindings
If the vulnerable WebView
registers any web interfaces, and you're able to redirect it to a website you control, then you can simply add JavaScript to your website that interacts with the app's code directly.
If you can read the app's source code, search for any calls to the addJavascriptInterface method, to find the name of the declared interface(s), and then you can find all of the exposed methods annotated with @JavascriptInterface
.
On your website, your JS code can call all of the exposed methods by using the window.interface_name.method_name
syntax.
Of course, the impact will vary depending on what the exposed methods allow you to do.
To see a more detailed example, check out this HackerOne report: https://hackerone.com/reports/401793.
2. Via Malicious app (< 24 SDK)
If the vulnerable WebView
can load local file://
URIs, you might be able exfiltrate all of the app's files with a little help from a malicious application.
Here are the steps:
- the malicious application writes an
HTML
file to a shared directory, accessible by the vulnerable app (e.g.:/sdcard
); - the malicious application sends an
Intent
to the vulnerable app that contains afile://
URI that matches the location of theHTML
file; - the
file://
URI is loaded by the vulnerableWebView
; - once the
HTML
file is loaded, the JS code declared inside this file reads all local files and sends them to a server you control.
Note that the following conditions need to be present in order for this to work:
- the malicious app needs to be granted the
WRITE_EXTERNAL_STORAGE
permission and needs to be able to write to a shared location, which is only possible before the enforcement of "scoped storage" (< SDK 30); - the vulnerable app needs to be granted the
READ_EXTERNAL_STORAGE
permission and needs to be able to read from a shared location, same reason as above; - the vulnerable app needs to be able to read
file://
URIs, which will throw an error after SDK 24 (you might get lucky if the developer actually intends for this to happen, and adds custom code to enable this behaviour); - the vulnerable
WebView
needs to have JS enabled.