OWASP Mobile Application Security Testing Guide: MASTG TEST 0028

---
masvs_v1_id:
- MSTG-PLATFORM-3
masvs_v2_id:
- MASVS-PLATFORM-1
platform: android
title: Testing Deep Links
masvs_v1_levels:
- L1
- L2
profiles: [L1, L2]
---

## Overview

Any existing [deep links](../../../Document/0x05h-Testing-Platform-Interaction.md#deep-links "Deep Links") (including App Links) can potentially increase the app attack surface. This [includes many risks](https://people.cs.vt.edu/gangwang/deep17.pdf) such as link hijacking, sensitive functionality exposure, etc.

- Before Android 12 (API level 31), if the app has any [non-verifiable links](https://developer.android.com/training/app-links/verify-android-applinks#fix-errors), it can cause the system to not verify all Android App Links for that app.
- Starting on Android 12 (API level 31), apps benefit from a [reduced attack surface](https://developer.android.com/training/app-links/deep-linking). A generic web intent resolves to the user's default browser app unless the target app is approved for the specific domain contained in that web intent.

All deep links must be enumerated and verified for correct website association. The actions they perform must be well tested, especially all input data, which should be deemed untrustworthy and thus should always be validated.

None of the input from these sources can be trusted; it must be validated and/or sanitized. Validation ensures processing of data that the app is expecting only. If validation is not enforced, any input can be sent to the app, which may allow an attacker or malicious app to exploit app functionality.

## Static Analysis

### Check for Android OS Version

The Android version in which the app runs also influences the risk of using deep links. Inspect the Android Manifest to check if `minSdkVersion` is 31 or higher.

- Before Android 12 (API level 31), if the app has any [non-verifiable deep links](https://developer.android.com/training/app-links/verify-android-applinks#fix-errors), it can cause the system to not verify all Android App Links for that app.
- Starting on Android 12 (API level 31), apps benefit from a [reduced attack surface](https://developer.android.com/training/app-links/deep-linking). A generic web intent resolves to the user's default browser app unless the target app is approved for the specific domain contained in that web intent.

### Check for Deep Link Usage

**Inspecting the Android Manifest:**

You can easily determine whether deep links (with or without custom URL schemes) are defined by @MASTG-TECH-0007 and inspecting the Android Manifest file looking for [`<intent-filter>` elements](https://developer.android.com/guide/components/intents-filters.html#DataTest "intent-filters - DataTest").

- **Custom Url Schemes**: The following example specifies a deep link with a custom URL scheme called `myapp://`.

  ```xml
  <activity android:name=".MyUriActivity">
    <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="myapp" android:host="path" />
    </intent-filter>
  </activity>
  ```

- **Deep Links**: The following example specifies a deep Link using both the `http://` and `https://` schemes, along with the host and path that will activate it (in this case, the full URL would be `https://www.myapp.com/my/app/path`):

  ```xml
  <intent-filter>
    ...
    <data android:scheme="http" android:host="www.myapp.com" android:path="/my/app/path" />
    <data android:scheme="https" android:host="www.myapp.com" android:path="/my/app/path" />
  </intent-filter>
  ```

- **App Links**: If the `<intent-filter>` includes the flag `android:autoVerify="true"`, this causes the Android system to reach out to the declared `android:host` in an attempt to access the [Digital Asset Links file](https://developers.google.com/digital-asset-links/v1/getting-started "Digital Asset Link") in order to [verify the App Links](https://developer.android.com/training/app-links/verify-android-applinks "Verify Android App Links"). **A deep link can be considered an App Link only if the verification is successful.**

  ```xml
  <intent-filter android:autoVerify="true">
  ```

When listing deep links remember that `<data>` elements within the same `<intent-filter>` are actually merged together to account for all variations of their combined attributes.

```xml
<intent-filter>
  ...
  <data android:scheme="https" android:host="www.example.com" />
  <data android:scheme="app" android:host="open.my.app" />
</intent-filter>
```

It might seem as though this supports only `https://www.example.com` and `app://open.my.app`. However, it actually supports:

- `https://www.example.com`
- `app://open.my.app`
- `app://www.example.com`
- `https://open.my.app`

**Using Dumpsys:**

Use @MASTG-TOOL-0004 to run the following command that will show all schemes:

```bash
adb shell dumpsys package com.example.package
```

**Using Android "App Link Verification" Tester:**

Use the [Android "App Link Verification" Tester](https://github.com/inesmartins/Android-App-Link-Verification-Tester) script to list all deep links (`list-all`) or only app links (`list-applinks`):

```bash
python3 deeplink_analyser.py -op list-all -apk ~/Downloads/example.apk

.MainActivity

app://open.my.app
app://www.example.com
https://open.my.app
https://www.example.com
```

### Check for Correct Website Association

Even if deep links contain the `android:autoVerify="true"` attribute, they must be _actually_ verified in order to be considered App Links. You should test for any possible misconfigurations that might prevent full verification.

#### Automatic Verification

Use the [Android "App Link Verification" Tester](https://github.com/inesmartins/Android-App-Link-Verification-Tester) script to get the verification status for all app links (`verify-applinks`). See an example [in the tool's README](https://github.com/inesmartins/Android-App-Link-Verification-Tester#use-an-apk-to-check-for-dals-for-all-app-links).

**Only on Android 12 (API level 31) or higher:**

You can use @MASTG-TOOL-0004 to test the verification logic regardless of whether the app targets Android 12 (API level 31) or not. This feature allows you to:

- [invoke the verification process manually](https://developer.android.com/training/app-links/verify-android-applinks#support-updated-domain-verification).
- [reset the state of the target app's Android App Links on your device](https://developer.android.com/training/app-links/verify-android-applinks#reset-state).
- [invoke the domain verification process](https://developer.android.com/training/app-links/verify-android-applinks#invoke-domain-verification).

You can also [review the verification results](https://developer.android.com/training/app-links/verify-android-applinks#review-results). For example:

```bash
adb shell pm get-app-links com.example.package

com.example.package:
    ID: 0