Intent Redirection Vulnerability
Risk: High - MASVS_CODE_4
Overview
An intent redirection occurs when an attacker can partly or fully control the contents of an intent used to launch a new component in the context of a vulnerable app.
The intent used to launch the new component can be supplied in several ways, most commonly either as a serialized intent in an
extrasfield, or marshaled to a string and parsed. Partial control of parameters can also lead to the same result.
The Code: Intent Redirection Vulnerability
Here’s the code we’re analyzing:
Intent intent = getIntent();
// Get the component name of the nested intent.
Intent forward = (Intent) intent.getParcelableExtra("key");
ComponentName name = forward.resolveActivity(getPackageManager());
// Check that the package name and class name contain the expected values.
if (name.getPackageName().equals("safe_package") &&
        name.getClassName().equals("safe_class")) {
    // Redirect the nested intent.
    startActivity(forward);
}Step-by-Step Explanation
- Receiving an External Intent: - Intent intent = getIntent();- The app receives an - Intentfrom an external source.
- Extracting a Nested Intent: - Intent forward = (Intent) intent.getParcelableExtra("key");- The app extracts another - Intent(called a nested intent) from the original- Intentusing the key- "key".
- Resolving the Component of the Nested Intent: - ComponentName name = forward.resolveActivity(getPackageManager());- The code determines the - Package Nameand- Class Nameof the nested intent’s target component.
- Validating the Target Component: - if (name.getPackageName().equals("safe_package") && name.getClassName().equals("safe_class")) {- It checks if the target package and class match the expected values ( - safe_packageand- safe_class).
- Redirecting the Nested Intent: - startActivity(forward);- If the validation passes, the app redirects the nested intent using - startActivity().
Where is the Vulnerability?
The vulnerability lies in the validation logic.
- The code only checks the package name and class name of the nested intent. 
- However, an attacker can craft a malicious nested intent that looks legitimate ( - safe_packageand- safe_classmatch) but contains harmful payloads.
Example of Exploiting the Vulnerability
An attacker can create an intent like this:
Intent maliciousIntent = new Intent();
Intent nestedIntent = new Intent();
nestedIntent.setComponent(new ComponentName("safe_package", "safe_class"));
// Add malicious data or actions
nestedIntent.putExtra("exploit_data", "malicious_data");
// Wrap the nested intent in the outer intent
maliciousIntent.putExtra("key", nestedIntent);
startActivity(maliciousIntent);Here’s what happens:
- The outer intent contains a nested intent ( - nestedIntent).
- The nested intent’s - ComponentNamematches the expected values (- safe_packageand- safe_class), so the validation passes.
- The app executes - startActivity(forward)and processes the malicious payload inside the nested intent (- exploit_data).
- If - safe_classhas a vulnerability or doesn’t properly validate the payload, the attack succeeds.
How to Mitigate the Vulnerability
As a rule of thumb, it's best to avoid exposing functionality related to redirecting nested intents. However, if the situation demands, use the following strategies for mitigation:
- Check where the intent is being redirected. 
- Use PendingIntent objects. This prevents your component from being exported and makes the target action intent immutable. 
- Use IntentSanitizer to make a sanitized copy of an Intent 
Apps can check where an intent is being redirected using methods such as ResolveActivity:
Intent intent = getIntent()
// Get the component name of the nested intent.
Intent forward = (Intent) intent.getParcelableExtra("key");
ComponentName name = forward.resolveActivity(getPackageManager());
// Check that the package name and class name contain the expected values.
if (name.getPackageName().equals("safe_package") &&
        name.getClassName().equals("safe_class")) {
    // Redirect the nested intent.
    startActivity(forward);
}Apps can use IntentSanitizer using logic similar to the following:
Intent intent = new  IntentSanitizer.Builder()
     .allowComponent("com.example.ActivityA")
     .allowData("com.example")
     .allowType("text/plain")
     .build()
     .sanitizeByThrowing(intent);Resources
Last updated
Was this helpful?




