1-Click Account Takeover via Deep Link Domain Validation Bypass
The Risk
A single tap on a link gave an attacker full control of any user's account on a cryptocurrency exchange. The stolen session token was valid for approximately 7 months, giving the attacker persistent access long after the initial compromise. The attack took under 2 seconds to complete and could be delivered via any messaging app, email, or website. Every logged-in user of the Android app was vulnerable.
The Vulnerability
The app's domain allowlist used a flawed string matching method that checked whether the URL "contained" the allowed domain, rather than checking that it ended with it. This meant a domain like "allowed-domain.attacker.com" would pass the check.
The app also exposed a JavaScript interface method that returned the user's live session token directly to any page loaded in the WebView.
The Attack
The attacker registered a domain that contained the exchange's domain name as a substring. A crafted deep link opened this attacker-controlled domain inside the app's WebView, which passed the domain check.
JavaScript on the attacker's page called the exposed interface method to retrieve the session token, then sent it to the attacker's server via an image request. The entire process completed in under 2 seconds with zero interaction beyond the initial tap.
The Impact
Full account takeover. The stolen session token was valid for approximately 7 months. The attacker could view all balances, access personal information, and execute trades.
The app also exposed 79 additional interface methods with no URL validation, including device fingerprinting and file access. The vendor patched the string matching method 12 days after the report was submitted.
Remediation
- Replace the string contains check with proper domain suffix matching.
- Remove the token-returning interface method entirely.
- Apply URL validation to all exposed interface methods.
- Reduce session token lifetime.