Deep links are an often overlooked way to exploit Android applications.
In this series I hope to do a deep dive into their history, common vulnerabilities with real-life examples, possible mitigations, and testing techniques for pentesters and researchers.
In this first part, we do a quick overview of the supported deep link formats in Android, and then quickly jump into the first vulnerability: Link Hijacking.
An Intro to Deep Links in Android
In short, deep links allow users to open specific content inside a mobile application.
In Android, there are 3 valid deep link formats:
Custom Scheme URLsor
Android App Links)
Intent Scheme URLs)
Note that the first 2 have an iOS equivalent, while the 3rd only exists in Android.
Scheme URLs were introduced with
Android 1.0 and
iOS 2.0 and clearly prioritised flexibility rather than security.
In this first iteration of deep links, any application can register any scheme, host and path, e.g.:
This means that there's no mechanism to ensure, for example, that all deep links with the
fb:// scheme are handled by the Facebook app.
If a user clicks on a deep link, the OS starts by checking which of the applications installed on the device have registered it:
- if there is only 1 application, the OS will automatically open the deep link with that application;
- if there is more than 1 application, the OS will check if any of them have previously been set as the "preference" - if so, the OS will open the link with that application;
- if there is more than 1 application and none of them have ever been set as the preference, the OS will prompt the user to choose between the apps.
Note that if the user clicks "Always" on this prompt, the chosen application becomes the preference, and the prompt will not be shown again.
Since any app can register any scheme, a victim application can become vulnerable to Link Hijacking, which we'll discussed in more detail at the end of this part.
App Links were introduced in 2015 with
Android 6 and
iOS 9 - note that in iOS they're called Universal Links.
App Links no longer support custom schemes, only
HTTPS. This makes the links "natively" compatible with any browser:
More important, when it comes to security, App Links introduced a mechanism that (at least in theory) prevents other apps from claiming a link: App Link Association.
App Link Association
The idea is pretty simple: to make sure that all
https://foo.com deep links are always handled by the
foo application, the team at Foo simply needs to add a specific file on the
foo.com server that contains the
SHA256 fingerprint of the
foo app's signing certificate - see more details here.
foo application is being installed on the device, its
AndroidManifest.xml file should indicate that it wants to register and verify the
https://foo.com App Link, and as a result the OS will check the aforementioned file - if everything's OK, no other app will be able to claim this link.
So, the good people at Foo no longer need to worry about Link Hijacking right? ... Nope.
First, we should note that iOS and Android have different policies when it comes to handling failed verifications:
- iOS prohibits opening unverified Universal Links;
- Android, however, leaves the decision up to users: if an unverified App Link is clicked, Android prompts users to choose if they want to open the link in the app or the browser.
Worse even, according to a 2017 study, most apps that use App Links are not correctly completing the verification process!
Some common errors included:
- Not creating the associate file
- Registering the App Link with a protocol that doesn't match the file (
- Having an invalid associate file
- Having an invalid manifest file
Finally, there is one type of Android app that is particularly vulnerable to link hijacking even when using App Links: Instant Apps.
This article won't go into detail regarding these vulnerabilities, but if you're interested I highly recommend this paper.
Finally, let's look at the least used deep link type: Intent URLs. They were introduced in 2013 and have a completely different syntax:
As you can see, the package name of the target app is explicitly specified, which means the OS doesn't prompt the user for their decision, making them resistant to the types of link hijacking detailed below.
As mentioned before, the fact that any application can register any Scheme URL, along with the improper implementation of App Links can make applications vulnerable to Link Hijacking, also known as "Deep Link Collision".
But, why is this an issue?
Imagine that a user installs a game application on their Android phone. Whenever the user opens the app they just see the game but, in fact, during installation this application registered a deep link that "belongs" to a banking app -
abcbank:// - which just so happens to be the user's bank.
One day this user happens to click on the same deep link registered by the "malicious" game app - this isn't strange since it's a valid deep link used by the actual ABC Bank.
Since the user doesn't yet have the
abcbank application installed on their phone, the OS will automatically open the link with the game app. However, now instead of showing the regular game UI, this malicious app displays a login screen that looks exactly like the login screen for
If the malicious application is able to trick the user into entering their
ABC Bank credentials on this login screen, it's game over.
Capturing Sensitive Data
As shown in this example, whenever deep links are used to communicate sensitive data such as authentication tokens, an attacker can use link hijacking to intercept this data.
In their 2017 study, "Measuring the Insecurity of Mobile Deep Links of Android", Liu et al. reviewed 160,000+ applications (retrieved from the Play Store) and found many instances of applications that seemed to be registering custom schemes for popular applications in order to boost traffic to their own app.
They found, for example, that
google.com is registered by 480 apps from 305 non-Google developers and that
google.navigation from Google Maps was hijacked by 79 apps from 32 developers.
In the same study mentioned above, it was found that a lot of applications register their competitors' schemes in order to trick users into using their apps:
For example, Careem (
com.careem.acma) and QatarTaxi (
com.qatar.qatartaxi) are two competing taxi booking apps in Dubai. Careem is more popular (5M+ downloads), which uses scheme
careemfor many functionalities such as booking a ride (from hotel websites) and adding credit card information.
QatarTaxi (10K downloads) registers to receive all
After code analysis, we find all these links redirect users to the QatarTaxi app’s home screen, as an attempt to draw customers.
Hope you found this useful, on the next part we'll try to see what happens when a user clicks on a malicious deep link.