offsecnotes

Deep link misconfiguration

by frankheat

Introduction

Types of links

(Custom) Scheme URI

App developers customize any schemes and URIs for their app without any restriction

E.g. fb://profile, geo://

<activity android:name=".MyMapActivity" android:exported="true"...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="geo" />
    </intent-filter>
</activity>

When the user clicks a deep link, a disambiguation dialog might appear. This dialog allows the user to select one of multiple apps, including your app, that can handle the given deep link


Web links

Web links are deep links that use the HTTP and HTTPS schemes.

Note: On Android 12 and higher, clicking a web link (not an Android App Link) opens it in a web browser. On earlier Android versions, users may see a disambiguation dialog if multiple apps can handle the web link.

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="http" />
    <data android:host="myownpersonaldomain.com" />
</intent-filter>

Android App Links

Android App Links, available on Android 6.0 (API level 23) and higher, are web links with the autoVerify attribute. This lets your app become the default handler for the link type, so when a user clicks an Android App Link, your app opens immediately if installed, without a disambiguation dialog.

<intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="http" />
    <data android:scheme="https" />
    <data android:host="myownpersonaldomain.com" />
</intent-filter>

In this case Android attempt to access the Digital Asset Links file in order to verify the App Links. A deep link can be considered an App Link only if the verification is successful.

Why might that be a problem?

Because of Link Hijacking. This happen when a malicious app registers an URI that belongs to the victim app. If mobile OS redirects the user to the malicious app, it can lead to phishing (e.g., the malicious app displays forged UI to lure user passwords) or data leakage (e.g., the deep link may carry sensitive data in the URL parameters such as session IDs).

Suppose that:

Android version Victim app installed Link supported URI Behavior
All N Custom scheme URI geo:// Open in malicious
All Y Custom scheme URI geo:// Dialog appear (malicious app, victim app)
< 12 N Web Links https://google.com Dialog appear (browser, malicious app)
< 12 Y Web Links https://google.com Dialog appear (browser, malicious app, victim app)
> 12 N / Y Web Links https://google.com Open in default browser
> 6 Y App Links https://google.com Open victim app

Start an intent

adb shell am start -W -a android.intent.action.VIEW -d "geo://"

Testing