Ever wondered the deep links that you have in your application is one of the doors for an attacker to crack your application?

The Zaheck of Android Deep Links!

Shiv Sahni
Apr 19 · 5 min read
Image for post
Image for post

In the current era of hybrid mobile architecture, the Webviews and Deep Links are extensively used hand in hand. The former one is used to deliver dynamic web content while the latter one is used to make the applications more interactive.

In this story, we would be discussing the common security misconfiguration pertaining to the mingling of Webview and Deep Link. We would majorly be discussing the amazing security research performed by Bagipro on Insufficient URL Validation and later we would be ending it with some recommendations to mitigate this issue.

The story is also meant for the security evangelists who might not have the understanding of fundamental concepts of Android system. The Prerequisites section covers a few of the concepts which are later used in the story if you are already clear with these fundamental concepts feel free to skip this section.

Prerequisites

Activity

An activity is one of the Android application components, in layman terms it can be considered as a screen. It has a user interface, which allows a user to interact with the application.

Image for post
Image for post
Usage of Intents For Communication

Intent and Intent Filters

An intent is a messaging object that allows communication between different application components such as Activity, Content Providers, Services, etc. It can be used for communication between application components of the same or different applications.

I strongly recommend you to have a look at Pg. 11 and 19 of The Grey Matter of Securing Android Applications paper to have a better understanding of the concept of Intents and Intent Filters.

Webview

Android allows developers to display web content directly into their application through Webviews. You can consider Webview as a dedicated web browser of an application.

What The Fish is Deep Link!?

While navigating web content on web browsers you might have observed the interaction wherein the browser invokes the specific application installed in your device to display the web content. The following GIF shows the interaction between browser and application through a deep link.

Image for post
Image for post

Deep links are nothing but specific URIs(Uniform Resource Identifiers) that must be handled by our application to improve the user experience. For example, fb://profile/33138223345 is a deep link, the URI contains all the information needed to launch directly into a particular location within the Facebook mobile app, in this case, the profile with id ‘33138223345’, i.e., the Wikipedia page, within the Facebook app.

Under the hood, we have an Android Activity which is to be invoked once a deep link is triggered. We usually call such Activities as Browsable Activities as they are configured to acknowledge the Browsable Category Intents. The Browsable Activity must have an intent filter defined with three elements viz. action, category and data as shown in the AndroidManifest.xml snippet below. You can read more about this here.

<activity
android:name="com.example.android.GizmosActivity"
android:label="@string/title_gizmos" >

<intent-filter android:label="@string/filter_view_example_gizmos">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE"/>
<!-- Accepts URIs that begin with "webviewdemoapp://” -->
<data android:scheme="webviewdemoapp"/>
</intent-filter>
</activity>
Image for post
Image for post

Note: We define the URI scheme in the data element using the android:scheme tag such that now Android system would not only acknowledge the URIs with this scheme(webviewdemoapp://) but would also invoke this Browsable Activity once such deep link is triggered, this is how a deep links work under the hood.

The Zaheck

Insufficient URL Validation

Usually, whenever we have a Webview component in the Browsable Activity and the idea is to load web URLs passed in the deep link URI, it is strongly advised to validate the URLs in order to prevent the load of arbitrary URLs.
In March 2019, a similar issue was reported by Bagipro in Grab Passenger Application and he was rewarded $7,500 for his amazing work. You can read more about it here.

For example if an application acknowledges the following deep link and opens the highlighted URL in the webview it is suggested that the proper validation should be performed.webviewdemoapp://issue=1&url=https://scripts.shivsahni.com/testsample.html

The following code snippet shows the validation while loading the URL in the webview

Uri uri = Uri.parse(deeplinkURL);/*https://scripts.shivsahni.com/testsample.html*/if("shivsahni.com".equals(uri.getHost() || uri.getHost().endsWith(".shivsahni.com"))
{
webView.loadUrl(deeplinkURL);}

Although the aforementioned URL validation appears to be sufficient to prevent the arbitary load of URLs but due to a problem in android.net.Uri and java.net.URL parsers the validation can still be bypassed and an adversary can still open malicious URLs in our application’s webview

The problem is that the android.net.Uri and java.net.URL parsers do not recognize backslashes in the authority part allowing an attacker to use backslashes in order to bypass the aforementioned validation. The same is depicted below:

String url = "http://attacker.com\\\\@legitimate.com/smth"; Log.d("Wow", Uri.parse(url).getHost()); // legitimate.com is printed
webView.loadUrl(url); // attacker.com is loaded

This extensive research was performed by Bagipro and you can read more about it here.

Lately, I did some more analysis on this and observed that the issue is now fixed for API level 28 and above since now triggering the deep links with malformed URLs loads the attacker's scripts in Chrome browser instead of Application’s webview. I tested this behaviour on Pixel XL devices.

Such issues can indeed become a P0 security issue, consider a scenario wherein the Privileged Webview(Ex: with JS Interfaces)is used to support such functionality, the lack of proper URL validation could allow an adversary to distribute the deep link with attacker-controlled URLs having malicious JavaScript which would even allow the execution of Java functions through the JS Bridges and thus may even lead to the exfiltration of user’s sensitive information such as PII and auth tokens. Moreover, the attack is remotely exploitable as an attacker just needs to host the malicious JavaScript and distribute the deeplink with malicious URL.

Recommendation

Although the issue was fixed in API level 28 and as per the statistics Android 9 occupies the major market share still we would need to support the previous APIs to keep the business as usual. It is suggested that the complete URL should be validated including the scheme, authority, etc. The best way to do that is by using regular expressions.

One of the suggested approaches is shown below:

private fun validateURL(urlString: String):Boolean{try {
URL urlObject= new URL(urlString);
if((urlObject.getAuthority()=="shivsahni.com") && (urlObject.getHost()=="https"))
return true;
}
catch (MalformedURLException e)
{
e.printStackTrace();
return false;
}
}

Apart from sufficient URL validations, it is also suggested that the webview should be hardened properly to control the impact in the scenario it is compromised. The following points can be kept in mind to harden the webview:

  1. Perform sufficient webview isolation by using Chrome Custom Tabs whenever you need to load non-trusted web content in your application webview
  2. Disable access of JavaScript::setJavaScriptEnabled(false), File System ::setAllowFileAccess(false)and Content Provider::setAllowConentAccess(false) from webview unless explicitly required.

You can refer this awesome confluence on hardening Android webviews.

InfoSec Write-ups

A collection of write-ups from the best hackers in the…

Sign up for Infosec Writeups

By InfoSec Write-ups

Newsletter from Infosec Writeups Take a look

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Shiv Sahni

Written by

Security Engineer |Security Consultant |Infosec Trainer | Author | Lecturer | Open Source Contributor | Learner https://www.linkedin.com/in/shivsahni/

InfoSec Write-ups

A collection of write-ups from the best hackers in the world on topics ranging from bug bounties and CTFs to vulnhub machines, hardware challenges and real life encounters. In a nutshell, we are the largest InfoSec publication on Medium. Maintained by Hackrew

Shiv Sahni

Written by

Security Engineer |Security Consultant |Infosec Trainer | Author | Lecturer | Open Source Contributor | Learner https://www.linkedin.com/in/shivsahni/

InfoSec Write-ups

A collection of write-ups from the best hackers in the world on topics ranging from bug bounties and CTFs to vulnhub machines, hardware challenges and real life encounters. In a nutshell, we are the largest InfoSec publication on Medium. Maintained by Hackrew