بِسْمِ اللَّهِ الرَّحْمَٰنِ الرَّحِيمِ
Today, we will discuss another duplicate vulnerability I found in the Samsung Dialer application. The vulnerability involves Intent Redirection, which I will explain first.
What Is Intent Redirection?
Intent Redirection is a vulnerability that occurs when an Android application forwards an incoming Intent to another component without properly validating or restricting its contents.
In Android, an Intent is used to request an action from another application component, such as an Activity, Service, or BroadcastReceiver.
A vulnerability can occur when an application receives an externally controlled Intent and then forwards or reuses it directly through methods such as:
startActivity(intent);
sendBroadcast(intent);
startService(intent);
Why Is Intent Redirection Dangerous?
If the receiving component is exported or otherwise accessible to other applications, an attacker may be able to craft a malicious Intent and send it to the vulnerable application.
The vulnerable application can then unintentionally act as a proxy, forwarding the attacker-controlled Intent to a sensitive component or privileged application.
Depending on the affected component and the privileges of the vulnerable application, this can potentially result in:
- Unauthorized activity launches
- Permission-check bypasses
- Triggering sensitive functionality
- Data leakage
- Privilege escalation
Samsung Dialer
Our target is the Samsung Dialer, where we discovered this issue in a system application.
We identified an exported activity protected by the CALL_PHONE permission.
The activity validates the incoming Intent by checking its action and whether the android.intent.extra.INTENT extra is present.
CALL_PHONE
The CALL_PHONE permission allows an application to initiate phone calls directly without requiring the user to manually confirm the call.
Unlike ACTION_DIAL, which opens the dialer with a phone number pre-filled, ACTION_CALL can initiate the call directly when the required permission is available.
The CALL_PHONE permission is used by applications such as WhatsApp, Telegram, Messenger, and Google Meet.
CALL_PRIVILEGED
CALL_PRIVILEGED is a restricted Android permission associated with privileged/system applications and is not intended for ordinary third-party applications.
It allows privileged applications, such as the system dialer, to perform certain calling operations that are not available to regular applications.
Unlike CALL_PHONE, which can be granted to applications through the normal Android permission model, CALL_PRIVILEGED is restricted to privileged/system contexts.
The Vulnerable Flow
The activity extracts an Intent from the caller-controlled extras and subsequently launches it using startActivity().
This means that an attacker can place a crafted Intent inside the android.intent.extra.INTENT extra and influence the final destination.
In this flow, the Intent originates from a third-party application and is received by the exported activity.
If the required extra is present, the application extracts the embedded Intent into a new intent2 object.
The application then checks that intent2 is not null and attempts to resolve it using PackageManager.resolveActivity().
If the embedded Intent can be resolved, the Dialer proceeds to launch it.
The important issue is that resolving an Intent does not establish that the caller is authorized to perform the requested action. The embedded Intent remains under the attacker's control.
PoC
The vulnerable activity trusts an embedded Intent supplied by a third-party application and launches it after performing only a basic resolution check.
This creates an Intent Redirection primitive where an attacker-controlled application can cause the Samsung Dialer to launch a selected Intent through its privileged execution context.
Attack Flow
┌──────────────────────────┐
│ Third-Party Application │
│ (Attacker Controlled) │
└────────────┬─────────────┘
│
│ 1. Send Intent containing
│ an embedded Intent
▼
┌──────────────────────────────┐
│ Exported Activity │
│ Samsung Dialer │
│ Protected by CALL_PHONE │
└────────────┬─────────────────┘
│
│ 2. Read Intent extra
│ android.intent.extra.INTENT
▼
┌──────────────────────────────┐
│ intent2 = Embedded Intent │
│ │
│ if (intent2 != null) │
└────────────┬─────────────────┘
│
│ 3. resolveActivity()
▼
┌──────────────────────────────┐
│ PackageManager │
│ │
│ Checks whether the Intent │
│ can be resolved │
└────────────┬─────────────────┘
│
│ 4. Intent resolved
▼
┌──────────────────────────────┐
│ startActivity(intent2) │
│ │
│ Dialer launches the attacker │
│ controlled Intent │
└────────────┬─────────────────┘
│
│ 5. Privileged
│ operation
▼
┌──────────────────────────────┐
│ Phone Call / Sensitive │
│ Operation │
└──────────────────────────────┘
Proof of Concept
Intent extra = new Intent("android.intent.action.CALL_PRIVILEGED");
extra.setData(Uri.parse("tel://911"));
Intent i = new Intent();
i.setComponent(new ComponentName(
"com.samsung.android.dialer",
"com.samsung.android.dialer.widget.recents.WidgetDuoCallStarterActivity"
));
i.setAction("ACTION_PLACE_DUO_CALL");
i.putExtra("android.intent.extra.INTENT", extra);
startActivity(i);
Conclusion
The root cause is the trust placed in an attacker-controlled embedded Intent.
Although the application performs a resolveActivity() check, this only verifies that the Intent can be resolved. It does not establish whether the originating application is authorized to request the resulting operation.
As a result, the exported Samsung Dialer activity can be abused as an Intent redirection primitive, allowing an attacker-controlled application to influence which component is launched through the Dialer's privileged context.
This issue was ultimately classified as a duplicate and tracked under SVE-2025-1217.