cordova-android
cordova-android copied to clipboard
Google Play Console: App rejected due to Intent Redirection vulnerability
Bug Report
Problem
Google Play Console: App rejected due to Intent Redirection vulnerability, org.apache.cordova.CordovaInterfaceImpl.startActivityForResu
What is expected to happen?
App should approve and publish without any issues
What does actually happen?
App rejects during the google play console review process
Information
Cordova Android application gets rejected during the play store review process. And their response is this,
We rejected xx with package name xx, for violating our Device and Network Abuse or User Data policy. This app uses software that contains security vulnerabilities for users or allows the collection of user data without proper disclosure.
The issue comes from this: org.apache.cordova.CordovaInterfaceImpl.startActivityForResult

The app .apk file works on Android devices without any issues.
Command or Code
AndroidManifest.xml
<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="11400" android:versionName="1.14.0" package="com.directfn.mobile.anbi_prod" xmlns:android="http://schemas.android.com/apk/res/android">
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
<uses-permission android:name="android.permission.INTERNET" />
<application android:allowBackup="false" android:debuggable="false" android:hardwareAccelerated="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:usesCleartextTraffic="true">
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode" android:label="@string/activity_name" android:launchMode="singleTop" android:name="MainActivity" android:screenOrientation="portrait" android:theme="@android:style/Theme.DeviceDefault.NoActionBar" android:windowSoftInputMode="adjustResize"
android:exported="true">
<intent-filter android:label="@string/launcher_name">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
</manifest>
Environment, Platform, Device
Android Google Play Console App Review
Checklist
- [x] I searched for existing GitHub issues
- [ ] I updated all Cordova tooling to most recent version
- [x] I included all the necessary information above
This is going to be difficult to find the root but I think the issue might be mixture of Cordova's very generic handling of intents and plugins that may start intents while the app contains sensitive permissions (such as SMS reading).
Google is a bit vague but does document the general issues and remediation for Intent Redirection. There isn't specific thing that can trigger this issue.
Due to the nature of this issue, I'll recommend forking cordova-android so that you can implement some suggestions in documented in the Google link above. If you make a change that Google then accepts, please do post your findings or perhaps even make a PR if the solution is generic enough.
Code in Question: https://github.com/apache/cordova-android/blob/954d3e0e7542356e6ea995ddc75dcb1db8bb36cc/framework/src/org/apache/cordova/CordovaInterfaceImpl.java#L66-L74
I have found this, could it help? https://stackoverflow.com/questions/62671106/onactivityresult-method-is-deprecated-what-is-the-alternative
It says that startActivityForResult has been deprecated and it shows different ways to approach the change.
Extracted from the link above:
public void openSomeActivityForResult() {
Intent intent = new Intent(this, SomeActivity.class);
someActivityResultLauncher.launch(intent);
}
// You can do the assignment inside onAttach or onCreate, i.e, before the activity is displayed
ActivityResultLauncher<Intent> someActivityResultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
// There are no request codes
Intent data = result.getData();
doSomeOperations();
}
}
});
registerForActivityResult can only be called inside onCreate, which is not exposed in plugins, adding support for registerForActivityResult would allow plugin developers to use the newer method