Android Deep Links vs App Links: How They Work and How to Check Them
A deep link is a link that opens a specific screen inside an Android app instead of just launching it. Verified App Links are the safer kind: Android confirms the website really belongs to the app, so the link opens the app directly with no chooser.
- Three kinds of link can open an app: custom-scheme deep links, plain web links, and verified Android App Links.
- App Links use Digital Asset Links statements hosted on the website to establish a verified association between the site and the app.[1]
- Verification is requested with
android:autoVerify="true"and checks a file at/.well-known/assetlinks.json.[2] - Any deep link is an entry point other apps and websites can trigger, so apps must treat the data in it as untrusted.
What a deep link is
Normally you open an app from its icon. A deep link lets a URL jump straight to a place inside it: a product page, a chat, a payment confirmation. Apps register for these links by declaring an intent filter in their manifest with a VIEW action, usually the BROWSABLE category, and a data element describing the URL pattern.
Three kinds of link
| Kind | Looks like | Verified? |
|---|---|---|
| Custom scheme | myapp://order/123 | No. Nothing proves the app owns the scheme. |
| Web link | https://example.com/order/123 | Not unless verification is set up. The user may see a chooser or the browser. |
| Android App Link | https://example.com/order/123 with verification | Yes. Android checked the site and the app belong together. |
Android describes App Links as a deep-linking capability in Android 6 and later that lets verified website URLs open the matching content in your app immediately, without a disambiguation dialog.[1]
How App Link verification works
- The app adds
android:autoVerify="true"to an intent filter. When it is present in at least one filter, installing the app on Android 6.0 (API level 23) or higher makes the system verify the hosts in its filters.[2] - Android fetches a Digital Asset Links file from each host at
https://hostname/.well-known/assetlinks.json.[2] - If the file lists the app's package name and signing certificate, the link is verified and opens in the app.
On Android 11 (API level 30) and lower, the system makes the app the default handler for those URL patterns only if it finds a matching Digital Asset Links file for all hosts in the manifest.[2]
The file's sha256_cert_fingerprints ties the website to a specific signer, which is why app signing matters here. Paxio uses the same mechanism: its website serves an assetlinks.json for the Paxio app.
The security risks
- Custom schemes can be claimed by more than one app. Because nothing verifies ownership, a malicious app can register the same scheme and try to intercept links meant for another app, so avoid putting sensitive tokens in them.
- Deep links are an entry point. Any app or web page can fire one, so the data it carries is untrusted input and must be validated. Android's guidance on exported components applies, since a deep-link activity must be exported to be reachable.[3]
- Unverified web links can open a chooser and let a look-alike app compete for the click.
- Broad patterns expose more. A filter matching a whole domain exposes more screens than one limited to specific paths.
OWASP groups this under the platform-interaction controls in MASVS-PLATFORM.[4]
How to read deep links in a manifest
<activity android:name=".LinkActivity" android:exported="true">
<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="https" android:host="example.com" android:pathPrefix="/app"/>
</intent-filter>
</activity>
Reading it: an exported activity, a VIEW and BROWSABLE filter, an https scheme and autoVerify, so this is a verified App Link for example.com/app. A data element with a made-up scheme and no autoVerify would be a custom-scheme deep link.
You do not have to read this by hand. Upload the APK to the APK analyzer: its Deep links table lists each link and labels it a verified App Link, an unverified web link or a custom-scheme deep link, with the component that handles it.
Good practice for developers
- Prefer verified App Links over custom schemes for anything user-facing.
- Validate and sanitize every parameter; never trust a deep link to carry authority.
- Keep filter patterns as narrow as the feature needs.
- Confirm that
assetlinks.jsonis served over HTTPS and lists the correct package and signing fingerprint. - Check the shipped APK, not just the source, to make sure the links behave as intended.
Frequently asked questions
What is the difference between a deep link and an App Link?
A deep link is any link that opens a specific place in an app. An Android App Link is a verified web link: Android confirmed the website belongs to the app, so it opens the app directly without asking.
What is assetlinks.json?
It is a Digital Asset Links file hosted at /.well-known/assetlinks.json on a website. It lists the apps, by package name and signing certificate fingerprint, that are allowed to handle the site's links.
What does android:autoVerify do?
It asks Android to verify the hosts in an intent filter when the app is installed, by checking each host's Digital Asset Links file. If verification succeeds the app handles those links directly.
Are custom-scheme deep links insecure?
They are less trustworthy because nothing proves the app owns the scheme, so another app could register the same one. They are fine for low-risk navigation, but avoid sending sensitive data through them.
Why does a link sometimes open in the browser instead of the app?
Usually because the link is not a verified App Link, the app does not handle that URL pattern, or the user chose the browser. Verified links open the app directly.
What does BROWSABLE mean in an intent filter?
The BROWSABLE category lets the activity be started from a web browser. It is what makes a link on a web page able to open the app.
Do deep links need the activity to be exported?
Yes. For other apps and browsers to start the activity, it must be exported, which is why deep-link handlers show up in an exported-components list.
Can a deep link be used to attack an app?
It can if the app trusts the link's data. A malicious page or app can craft a link with unexpected parameters, so handlers must validate everything and avoid performing sensitive actions on their own.
How can I see an app's deep links?
Upload its APK to App Checker's analyzer, which lists each deep link with its type and handling component, or read the intent filters in the AndroidManifest.xml yourself.
- About Android App Links — Android Developers — what App Links are and how Digital Asset Links verify the association.
- Verify Android App Links — Android Developers — autoVerify, the assetlinks.json location and verification by Android version.
- Android exported components risk — Android Developers — risks of exposing components to other apps.
- OWASP MASVS — MASVS-PLATFORM — secure interaction with the platform and other apps.