Every mobile app and web platform relies on deep links to deliver seamless user experiences. A single link can send a user straight to a checkout page, a shared document, a profile, or a password reset screen. That convenience, however, is exactly what makes deep links a prized target for attackers.
When deep link security is poorly implemented, attackers can hijack sessions, redirect users to malicious destinations, bypass authentication, and steal sensitive tokens without the victim ever noticing. This guide breaks down how deep link exploitation actually works, where developers go wrong, and the concrete steps your team must take to shut down these attack paths before they are weaponized against your users.
If your organization handles mobile apps, OAuth flows, or dynamic links at scale, you cannot afford to treat this as a secondary concern. Deep link security is a first-class attack surface.
Deep links are URLs that navigate users directly to specific content within an application rather than dropping them on a homepage. They exist in several forms:
Traditional deep links use custom URI schemes like myapp://profile/settings and are registered at the OS level.
Universal links (iOS) and App Links (Android) use standard HTTPS URLs like https://myapp.com/profile/settings and are cryptographically associated with a specific app through verified domain ownership files.
Deferred deep links handle the case where the app is not yet installed, routing users through an install and then to the intended destination.
Each of these mechanisms carries distinct security implications. Universal and App Links are significantly more secure by design because they require domain verification. Traditional URI schemes, on the other hand, are wide open by default and have been exploited in the wild for years.
The deeper problem is that deep links often carry sensitive parameters including authentication tokens, session identifiers, payment references, and user-specific data. When those links are intercepted, forged, or hijacked, the consequences range from account takeover to financial fraud.
Understanding the attack surface is the first step to closing it. Here are the most commonly abused deep link attack patterns observed in real-world pentesting engagements.
On Android, any application can register a custom URI scheme. If your app uses myapp://auth/callback as an OAuth redirect URI, a malicious app installed on the same device can register the same scheme and intercept the callback. The OS has no preference mechanism and may silently route the intent to the attacker's app, handing over an authorization code or access token.
This is not a hypothetical. It has been exploited against major platforms, and it is one of the primary reasons the OAuth 2.0 security best practices RFC (8252) explicitly discourages custom scheme redirects for native apps.
OAuth and OpenID Connect flows are particularly vulnerable. The authorization code is typically delivered through a redirect URI. If that redirect lands in a deep link that is not properly verified, an attacker who controls another app on the device or who can manipulate the link itself can steal the code before your app processes it.
This attack becomes especially effective when:
state parameterDeep links often carry query parameters that drive application logic. Parameters like ?redirect=/dashboard, ?token=abc123, or ?user_id=9982 are frequently passed without server-side validation. An attacker who understands your link structure can manually craft URLs that:
Android's Intent system is the backbone of deep link routing. Activities that handle deep links must explicitly declare which URI patterns they accept. When an activity is exported without restrictions, any application on the device can send crafted Intents to it, potentially bypassing access controls or injecting malicious parameters directly into sensitive workflows.
When a deep link contains a sensitive token in the URL path or query string and the user is redirected during that flow, the token can leak through the HTTP Referer header to third-party scripts, analytics tools, or advertising networks embedded in the destination page. Many teams embed session tokens in deep links without considering that standard browser and app behavior will broadcast them to every third party that gets a Referer header.
Deep link vulnerabilities frequently survive security reviews for a predictable set of reasons. They sit at the boundary between mobile and web security, meaning web-focused reviewers often assume they are covered by the mobile team, and vice versa. Automated scanners rarely model intent-based attack paths. And because deep links often work correctly in happy-path testing, developers assume they are secure.
This gap is exactly why specialized mobile and API penetration testing matters. A targeted assessment can trace intent flows, evaluate URI scheme registrations, test OAuth redirect handling, and simulate the full range of interception scenarios that a generic scan will miss.
If your team has not had your deep link architecture reviewed by specialists, the gap almost certainly exists. Redfox Cybersecurity's penetration testing services cover mobile application security with the depth and precision this attack surface demands.
The single highest-impact change most mobile teams can make is to migrate away from custom URI schemes toward Universal Links on iOS and App Links on Android. Both mechanisms require verifiable domain ownership through digitally signed association files:
iOS: Host an apple-app-site-association (AASA) file at https://yourdomain.com/.well-known/apple-app-site-association. This file must be valid JSON, served over HTTPS without redirects, and signed through Apple's CDN.
Android: Host a assetlinks.json file at https://yourdomain.com/.well-known/assetlinks.json. This file must declare your app's package name and the SHA-256 fingerprint of your signing certificate.
When these files are correctly configured, the OS verifies app ownership before routing links. No other app can claim your domain-backed links. This closes URI hijacking entirely for traffic that follows these flows.
If your app uses OAuth 2.0 or OIDC and delivers authorization codes through deep links, PKCE is non-negotiable. PKCE works by having your app generate a random code verifier, hash it to produce a code challenge, and send that challenge with the initial authorization request. When the authorization code arrives through the deep link, your app must exchange it along with the original verifier, which the authorization server validates.
Even if an attacker intercepts the authorization code via URI hijacking, they cannot exchange it without the verifier, which never left your app. PKCE effectively breaks the interception chain for OAuth token theft via deep links.
// Generate PKCE pair
const codeVerifier = base64url(crypto.getRandomValues(new Uint8Array(32)));
const codeChallenge = base64url(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(codeVerifier)));
// Include in authorization request
const authUrl = `https://auth.example.com/authorize?
response_type=code&
client_id=YOUR_CLIENT_ID&
redirect_uri=https://yourapp.com/callback&
code_challenge=${codeChallenge}&
code_challenge_method=S256&
state=${secureRandomState}`;
[cta]
Validate the state parameter on return to prevent CSRF. Tie the state value to your session and reject any callback that does not match exactly.
Never trust parameters arriving through a deep link. Treat them with the same suspicion you would apply to any user-controlled input from an HTTP request. Apply the following controls:
user_id=5543 must be confirmed to match the authenticated user before acting on it.Review every Activity in your AndroidManifest.xml that handles deep links. Apply these controls:
Set android:exported="false" on any Activity that should not be reachable from outside your app. For Activities that must accept external intents for legitimate deep links, use intent filters with explicit URI pattern matching and validate every incoming Intent within the Activity's onCreate and onNewIntent handlers.
Consider using android:autoVerify="true" in your intent filter alongside a valid assetlinks.json to enable App Links verification, which restricts handling to your verified app only.
<activity android:name=".DeepLinkActivity" 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="yourapp.com"
android:pathPrefix="/secure/" />
</intent-filter>
</activity>
[cta]
Sensitive tokens do not belong in URLs, and therefore do not belong in deep links. If your authentication flow requires passing a token to the app, pass a short-lived, opaque code that your server can exchange for the actual credential. The code should be:
This eliminates Referer header leakage, log exposure, and token interception as meaningful attack paths even if the deep link itself is captured.
For web-based deep link landing pages, configure your Referrer-Policy header to no-referrer or strict-origin-when-cross-origin. This prevents sensitive URL parameters from leaking to third-party scripts through the Referer header.
Referrer-Policy: strict-origin-when-cross-origin
[cta]
Also audit your analytics, A/B testing, and advertising scripts. These third parties routinely capture the full page URL, including query parameters. If tokens are present in deep link URLs, they are being shared with every script on the landing page.
Defense requires validation. After implementing these controls, you need to verify they hold under adversarial conditions. The following tests should be part of your mobile security testing protocol:
Running these tests internally provides a baseline. Having them run by specialists with adversarial expertise finds what your internal team does not know to look for. Redfox Cybersecurity's mobile and web application pentesting services include comprehensive deep link attack surface assessments that go well beyond checkbox compliance.
Security is not a one-time configuration. Deep link attack surfaces evolve as your application grows, as new OAuth flows are added, as third-party SDKs are integrated, and as the OS platforms update their security models.
Build deep link security into your development lifecycle:
Deep link exploitation is not a niche vulnerability class. It sits at the intersection of mobile, web, and identity security and has led to real account takeovers, token theft, and data breaches across consumer and enterprise platforms alike. The attack techniques are well-documented, the tools are accessible, and the majority of apps in production have at least one exploitable weakness in their deep link handling.
The good news is that the defenses are also well-understood. Universal Links, App Links, PKCE, server-side parameter validation, and strict intent controls collectively close the most impactful attack paths. What most teams lack is not the knowledge that these controls exist, but the structured process to implement and verify them before an attacker finds the gap.
That is where professional security assessment changes the equation. Redfox Cybersecurity works with development and security teams to identify, validate, and remediate deep link vulnerabilities across mobile and web platforms. Whether you are preparing for a product launch, a compliance audit, or simply want to understand your actual exposure, a focused penetration test gives you the evidence-based picture you need to prioritize and act with confidence.
Do not wait for a breach to discover how your deep links are handled under adversarial conditions. Reach out to Redfox Cybersecurity and get a clear picture of your attack surface today.