Remediation for Intent Redirection Vulnerability

This information is intended for developers with app(s) that contain the Intent Redirection Vulnerability.

What’s happening

One or more of your apps contain an Intent Redirection issue which can allow malicious apps to access private app components or files. Please review the detailed steps below to fix the issue with your apps. After the deadlines shown in your Play Console, any apps that contain unfixed security vulnerabilities will be removed from Google Play.

Action required​

  1. Sign in to your Play Console, and navigate to the Alerts section to see which apps are affected and the deadlines to resolve these issues.
  2. Update your affected apps using the steps highlighted below.
  3. Submit the updated versions of your affected apps.

Upon resubmission, your app will be reviewed again. This process can take several hours. If the app passes review and is published successfully, then no further action is required. If the app fails review, then the new app version will not be published and you will receive an email notification.

Additional details

Apps that extract Intents from the Extras field of an untrusted Intent and launch a component by calling startActivity (or similarly, startService, or sendBroadcast) on an extracted Intent can be tricked into (1) launching an unintended private component which can lead to performing sensitive actions with poisoned arguments, and/or (2) unintentionally launching another app's components, which can lead to having sensitive files stolen through granted URI permissions.

We recommend that you prevent this vulnerability in one of the following ways:

Option 1: Make the affected app component, from which the extracted Intent is redirected, private.

If the affected app component does not need to receive Intents from other apps then you can make that app component private by setting android:exported=”false” in your Manifest.

Option 2: Ensure that the extracted Intent is from a trustworthy source.

You can verify that the originating Activity can be trusted using methods like getCallingActivity. For example:

 // check if the originating Activity is from trusted package
 if (getCallingActivity().getPackageName().equals(“known”)) {
   Intent intent = getIntent();
   // extract the nested Intent
   Intent forward = (Intent) intent.getParcelableExtra(“key”);
   // redirect the nested Intent
   startActivity(forward);
 }

Note:

  • Checking if getCallingActivity() returns a non-null value is insufficient to prevent the vulnerability. Malicious apps can supply a null value for this function.
  • In the case of Google Play Services SMS Retriever Auth, protecting a broadcast receiver with the SEND_PERMISSION will ensure that an Intent comes from Play Services.

Option 3: Ensure that the to-be-redirected Intent is not harmful.

You should verify that the redirected Intent

  1. will not be sent to any of your app’s private components, and
  2. will not be sent to an external app's component. If the redirect is intended to target an external app, be sure the intent will not grant a URI permission to one of your app’s private content providers.

Apps can check which component will be used to handle the Intent before redirecting it using methods like resolveActivity. For example:

 Intent intent = getIntent();
 // extract the nested Intent
 Intent forward = (Intent) intent.getParcelableExtra(“key”);
 // get the component name
 ComponentName name = forward.resolveActivity(getPackageManager());
 // check that the package name and class name are as intended
 if (name.getPackageName().equals(“safe_package”) &&
     name.getClassName().equals(“safe_class”)) {
   // redirect the nested Intent
   startActivity(forward);
 }

Apps can check whether an Intent grants a URI permission using methods like getFlags. Apps can also remove grants of URI permissions using removeFlags. For example:

 // extract the nested Intent
 Intent forward = (Intent) intent.getParcelableExtra(“key”);
 // get the flags
 int flags = forward.getFlags();
 // check that the nested intent does not grant URI permissions
 if ((flags & Intent.FLAG_GRANT_READ_URI_PERMISSION == 0) &&
     (flags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION == 0)) {
   // redirect the nested Intent
   startActivity(forward);
 }

Understanding Alerts and Choosing a Prevention Option 

The Play Console alert reports where your app launches another component using an untrusted extracted Intent. To better understand which prevention option is most appropriate, trace back and look at callers of methods to find where the launch Intent is extracted from an untrusted Intent. For example, for Option 1, trace back to determine which component to make private.

We’re here to help

If you have technical questions about the vulnerability, you can post to Stack Overflow and use the tag “android-security.” For clarification on steps you need to take to resolve this issue, you can contact our developer support team.

Was this helpful?
How can we improve it?