# Intent Redirection Vulnerability

### **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 `extras` field, 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:

```java
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**

1. **Receiving an External Intent:**

   ```java
   Intent intent = getIntent();
   ```

   The app receives an `Intent` from an external source.
2. **Extracting a Nested Intent:**

   ```java
   Intent forward = (Intent) intent.getParcelableExtra("key");
   ```

   The app extracts another `Intent` (called a nested intent) from the original `Intent` using the key `"key"`.
3. **Resolving the Component of the Nested Intent:**

   ```java
   ComponentName name = forward.resolveActivity(getPackageManager());
   ```

   The code determines the `Package Name` and `Class Name` of the nested intent’s target component.
4. **Validating the Target Component:**

   ```java
   if (name.getPackageName().equals("safe_package") &&
        name.getClassName().equals("safe_class")) {
   ```

   It checks if the target package and class match the expected values (`safe_package` and `safe_class`).
5. **Redirecting the Nested Intent:**

   ```java
   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_package` and `safe_class` match) but contains harmful payloads.

***

#### **Example of Exploiting the Vulnerability**

An attacker can create an intent like this:

```java
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:

1. The outer intent contains a nested intent (`nestedIntent`).
2. The nested intent’s `ComponentName` matches the expected values (`safe_package` and `safe_class`), so the validation passes.
3. The app executes `startActivity(forward)` and processes the malicious payload inside the nested intent (`exploit_data`).
4. If `safe_class` has 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](https://developer.android.com/reference/kotlin/androidx/core/content/IntentSanitizer) to make a sanitized copy of an Intent

Apps can check where an intent is being redirected using methods such as [`ResolveActivity`](https://developer.android.com/reference/android/content/Intent#resolveActivity\(android.content.pm.PackageManager\)):

```java
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`](https://developer.android.com/reference/kotlin/androidx/core/content/IntentSanitizer) using logic similar to the following:

```java
Intent intent = new  IntentSanitizer.Builder()
     .allowComponent("com.example.ActivityA")
     .allowData("com.example")
     .allowType("text/plain")
     .build()
     .sanitizeByThrowing(intent);
```

***

### Resources

{% embed url="<https://docs.ostorlab.co/kb/INTENT_REDIRECTION/index.html>" %}

{% embed url="<https://developer.android.com/privacy-and-security/risks/intent-redirection#java>" %}

{% embed url="<https://medium.com/androiddevelopers/android-nesting-intents-e472fafc1933>" %}

{% embed url="<https://mfallahpour.medium.com/what-is-android-intent-redirection-vulnerability-and-how-to-prevent-it-7cea70b052db>" %}

{% embed url="<https://medium.com/@0x3adly/android-intent-redirection-a-hackers-gateway-to-internal-components-ebe126bbb2e0>" %}

{% embed url="<https://github.com/MasoudFallahpour/IntentRedirectionVulnerableApp>" %}

{% embed url="<https://support.google.com/faqs/answer/9267555?hl=en-AU>" %}
