← Back to all reports

Push Notification Forgery via Exported Activity Leads to Zero-Click Account Takeover

Reported Mar 4, 2026
Severity Critical
Platform Android
Vulnerability Class Improper Access Control (CWE-926)
Target Type Cryptocurrency Exchange
Impact Full account takeover + trading access

The Risk

If a user had a simple utility app installed on the same phone as this crypto exchange, the attacker could silently steal their full account access without the user ever tapping anything. No notification shown, no permission requested, no interaction needed. The attacker would then have the ability to view all balances, place trades, and access personal information. Tested successfully 5 out of 5 times on two different devices.

The Vulnerability

Exported Activity with No Permission Check

The app's push notification handler activity was marked as exported with no permission restriction. Any installed app could send it an intent carrying a crafted encrypted payload. The activity would decrypt it, extract a URL, and open it in an internal WebView that injected the user's authentication tokens as HTTP request headers.

Fully Deterministic Encryption

The payload encryption used SM4-CBC where the key was derived from MD5("prefix" + f(timestamp)). The function f() was a simple lookup table based on timestamp % 10. The timestamp itself was appended to the ciphertext after a separator character. This means an attacker picks any timestamp, computes the key deterministically, encrypts any payload they want, and delivers it. No server secret, API key, or push infrastructure access needed.

The Attack

  1. Malicious app (zero permissions, appears as a normal utility) is installed on the victim's device
  2. The app sends a wake intent to the exchange app's exported launcher activity (500ms delay)
  3. After the exchange loads, the malicious app forges an SM4-encrypted payload containing an attacker URL
  4. The payload is sent via intent to the exported push handler activity
  5. The activity decrypts it, extracts the URL, and opens it in a WebView
  6. The WebView automatically injects the user's login token, access token, and device ID as HTTP headers on the request
  7. The attacker's server captures the complete session credentials

No notification is shown to the user. No tap is required. The entire chain executes in under 4 seconds.

The Impact

The WebView injected three authentication headers on every request:

  • Full session token (used for all authenticated API calls)
  • API access token (64-character hex)
  • Device fingerprint

With these tokens, confirmed API access included: full profile with email and 2FA status, all balances, placing spot orders, changing account settings, viewing transaction history, and signing out the victim.

Fund Drain Scenario

An attacker could place market orders on the victim's account against their own orders on the opposite side of the order book, effectively draining funds through legitimate-looking trades without needing withdrawal access.

Test Results

5 out of 5 successful token captures across 2 physical devices (one rooted, one stock), testing both warm start (app already running) and cold start (app not in memory). The vendor silently patched in a subsequent release by removing the exported flag from the activity.

Remediation

  • Remove the exported flag from the push handler activity or add a signature-level permission
  • Validate notification URLs against an allowlist of owned domains
  • Do not inject authentication tokens into WebViews loading external URLs
  • Use proper authenticated encryption with a server-distributed secret instead of deterministic key derivation