Deep Link & Intent Hijacking
Android’s intent system is a powerful inter-component communication mechanism — and a rich attack surface. This post covers the full range of intent-based vulnerabilities from deep link injection to task hijacking.
Android Intents — Quick Primer
An Intent is a messaging object used to request an action from another app component. There are two types:
- Explicit Intent — specifies the target component by name. Used for intra-app communication.
- Implicit Intent — describes the action, letting the OS find a matching component. Any app can register to handle implicit intents.
Deep links are URLs that trigger an Intent, launching a specific app or activity.
Enumerating the Attack Surface
Manifest analysis
|
Look for:
- Activities, services, or receivers with
exported="true"(or no permission) <data>tags defining URI schemes (deep links)<action android:name="android.intent.action.VIEW">+<category android:name="android.intent.category.BROWSABLE">— accessible from browser
drozer
|
Deep Link Testing
Deep link formats
|
Triggering via ADB
|
Common deep link vulnerabilities
Open Redirect:
|
If the app opens the redirect URL without validation — redirect to phishing page.
WebView URL Injection:
|
If the app passes the url parameter to a WebView without validation, you get XSS in the app’s WebView context — potentially accessing JavaScript bridges.
Token Leakage:
If a deep link carries a session token and the activity is exported, any other app can read it:
|
|
Actually, the attacker’s own exported activity can register for the same scheme and steal the token before the legitimate app handles it (if scheme-based, not App Links).
Implicit Intent Interception
When an app sends an implicit intent (e.g., share, open file, pick contact), any app can register to handle it.
Vulnerable code:
|
A malicious app with the same intent filter captures the data. This is the “confused deputy” problem.
Testing implicit intents with drozer
|
Task Hijacking (StrandHogg)
StrandHogg — malicious app configures android:taskAffinity to match the target app and allowTaskReparenting=true. The malicious activity reparents into the target app’s task.
When the user next launches the target app, the malicious activity appears instead.
Vulnerable configuration:
|
StrandHogg 2.0 — exploits a flaw in the startActivities() API, no manifest config needed. Fixed in May 2020 security patch.
Testing
|
Exported Activity Direct Launch
Any exported activity without permission can be launched directly, bypassing navigation guards:
|
Exported Services
Services handle background tasks. If exported, they can be triggered externally.
|
App Links vs. Custom Schemes
Custom URI schemes (target://) can be intercepted by any installed app that registers the same scheme. No trust mechanism.
Android App Links (https://) require the domain to host a .well-known/assetlinks.json file, cryptographically binding the app to the domain. Much harder to hijack.
Check the asset links file:
|
If the app relies on custom schemes for OAuth callbacks, this is a finding — use App Links instead.
OAuth Redirect URI via Deep Link
OAuth flows using custom scheme redirect URIs are vulnerable to interception:
|
The malicious app receives the authorization code.
Bypassing Deep Link Validation
If the app validates the host:
|
Try bypass:
|
Remediation
- Use App Links (verified HTTPS) instead of custom URI schemes for OAuth and sensitive flows.
- Do not pass deep link parameters directly to WebView — validate and whitelist URLs.
- Mark sensitive activities with
exported="false"and protect them withandroid:permission. - Validate all intent extras before use — type-check, range-check, whitelist values.
- Don’t use implicit intents to transmit sensitive data — use explicit intents or secure IPC.
- Set
android:taskAffinity=""on all activities to prevent StrandHogg.
Discussion
Leave a comment · All fields required · No spam
No comments yet. Be the first.