Android dialer flaw enables one-tap call forwarding hijack via MMI codes
Security researcher demonstrates how vulnerable dialer apps with CALL_PHONE permission can execute MMI codes silently through a single web link tap, registering call forwarding without user consent. Google classifies the issue as a third-party app problem, not an OS vulnerability.
A security researcher has demonstrated a chain of vulnerabilities that allows an attacker to register call forwarding on an Android device with a single tap on a web link, intercepting incoming calls including one-time passcodes and bank verification callbacks.
The attack exploits the CALL_PHONE runtime permission — granted to apps like WhatsApp, Signal, and Truecaller — which also authorizes execution of Man-Machine Interface (MMI) and Unstructured Supplementary Service Data (USSD) codes. These codes, such as * 21 #, configure carrier-level services including unconditional call forwarding.
The researcher, writing under the handle karansaini, identified the issue after scanning 88 call, dialer, and VoIP applications. Of those, 66 declared CALL_PHONE and 54 exposed browser-reachable dialer deeplinks. Not all auto-dial the supplied string; many only pre-fill the dialer. But those that do auto-dial create a remote attack surface.
Demonstration via ACR Phone
ACR Phone / Cube ACR (com.nll.cb, over 5 million installs) declares an intent filter with action CALL_BUTTON, category BROWSABLE, and a tel: data scheme. Its resolved activity passes the tel: data into an auto-dial path. Chrome's intent: URI syntax allows a web page to nominate CALL_BUTTON as the action. Chrome only verifies that the resolving filter declares BROWSABLE; it does not filter the action itself.
A single tap on a crafted link — intent:*123%23#Intent;scheme=tel;action=android.intent.action.CALL_BUTTON;end — triggers ACR's auto-dial path. The terminating hash must be percent-encoded as %23; a literal hash is lost during intent parsing and the string becomes an ordinary call.
On a Samsung Galaxy M16 5G running Android 16 (One UI 8.5, security patch 5 July 2026) with an Airtel India SIM, the researcher confirmed that *21* %23 registered unconditional call forwarding. The network returned a successful-registration response and a persistent diversion indicator appeared in the status bar. A call placed to the target device from a third phone arrived on the attacker's line; the target handset never rang.
The same behavior reproduced on an Android 17 emulator. Forwarding can be cleared with ##21# and interrogated with *#21# .
Android 17 platform change removes need for vulnerable app
Testing on Android 17 revealed a related platform change. Android 17 moves Telecom into the com.android.telephonycore mainline module and splits its UI into a separate privileged application, com.google.android.telecomui. The original caller's package identity is not carried across this hand-off. Since telecomui holds CALL_PRIVILEGED, the framework evaluates the call under a privileged dialer identity, skipping the check that would otherwise reject dangerous MMI strings.
The effect: on Android 17, a plain **21* # sent through ACTION_CALL by any app holding only CALL_PHONE — with no dialer role and no vulnerable third-party app in the path — is dispatched as an MMI code. The researcher reported this separately on 14 September 2026; Google closed it on 24 September as a duplicate of an internal issue reported by a Google engineer.
Impact and mitigation
Call diversion converts code execution into call interception. For as long as the diversion remains registered, the attacker receives the victim's incoming calls. The carrier stores the registration; rebooting, uninstalling the dialer app, or factory resetting the device does not cancel it. The only visible artifacts are the brief USSD dialog and the status-bar diversion indicator, which few users recognize or attribute to a prior link tap.
The researcher argues that the permission grant does not constitute informed consent for MMI execution, and that the consequence class differs from silent voice calls: silent forwarding costs nothing, intercepts calls, and leaves no log entry. Google already treats USSD as dangerous elsewhere, restricting its use in Play policy.
Suggested fixes include a confirmation prompt displaying the literal MMI code before execution for non-default dialers, or decoupling the capability entirely — keeping CALL_PHONE for dialing and gating MMI execution behind a distinctly worded permission or explicit confirmed API, similar to TelephonyManager.sendUssdRequest().
Disclosure and response
The researcher reported the CALL_PHONE/MMI issue to the Android & Google Devices Vulnerability Reward Program on 12 September 2026, with an Android 17 retest on 14 September. Google closed the report on 17 September as "Won't Fix (Infeasible)," assessing it as a consequence of insecure deeplink handling in third-party dialer apps rather than an OS vulnerability. Google stated that platform hardening would be treated as a future improvement, not a security fix.
The researcher disagrees, noting that security then rests on every call-capable app's deeplinks being reviewed for auto-dial paths, which is not feasible.
On 9 October, the researcher reported the ACR Phone deeplink issue to its developer. The developer acknowledged within 48 minutes, committed a fix to the release, and supplied a beta build for verification. The same component was previously the subject of CVE-2024-36064, reported by Edward Warren, which allowed any installed app without permissions to place a call with no user interaction. The two issues a root cause: an exported entry point into the dial path that validates neither its caller nor its payload.
CALL_PHONE and MMI execution
12 Sep 2026 — Reported to Android & Google Devices VRP
14 Sep 2026 — Added Android 17 retest
17 Sep 2026 — Closed as Won't Fix (Infeasible)
09 Oct 2026 — Reported deeplink issue to ACR Phone developer
09 Oct 2026 — ACR Phone developer acknowledged, fix committed
09 Oct 2026 — Public disclosure
14 Sep 2026 — Reported to Android & Google Devices VRP as separate issue
24 Sep 2026 — Closed as duplicate of internal Google engineer report
25 Sep 2026 — Request to join original report declined
09 Oct 2026 — Public disclosure
Source : karansaini.com
The full story
This article is one source in a clustered incident — the cluster page carries the summary, timeline and every other outlet covering it.
