Intent redirections are intents forwarded by a component to another component. It can lead to vulnerabilities such as leak of information when an
exported component of the mobile app, like an activity, doesn’t validate an untrusted intent used to start a component, ie to perform the intent
redirection.
Noncompliant Code Example
A component activity is exported (in this case using an intent-filter) allowing it to be launched by other mobile applications:
<activity android:name=".Noncompliant">
<intent-filter>
<action android:name="noncompliantaction" />
</intent-filter>
</activity>
Then this activity retrieves the embedded untrusted intent used to start an arbitrary component:
public class Noncompliant extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// The intent used to start this exported component is retrieved
Intent intent = getIntent();
// extract the embedded Intent
Intent forward = (Intent) intent.getParcelableExtra("anotherintent");
// redirect the embedded Intent
startActivity(forward); // Noncompliant
}
}
Compliant Solution
If it’s not needed to make visible this component to other apps, do not export it:
<activity android:name=".Noncompliant" android:exported="false">
<intent-filter>
<action android:name="noncompliantaction" />
</intent-filter>
</activity>
It’s also possible to validate the intent to be sure it’s the expected one:
public class Noncompliant extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// The intent used to start this exported component is retrieved
Intent intent = getIntent();
// extract the embedded Intent
Intent forward = (Intent) intent.getParcelableExtra("anotherintent");
ComponentName name = forward.resolveActivity(getPackageManager());
if (name.getPackageName().equals("package") &&
name.getClassName().equals("nonsensitiveclass")) {
// redirect the embedded Intent
startActivity(forward);
}
}
}
See