PendingIntent, the advanced version of normal Android Intent, provides powerful inter-component communication on Android. A PendingIntent holds a base Intent that can be executed by another app under the creator app's identity (UID) and permissions as if the target app was the creator. To securely deliver a PendingIntent and prevent hijacking, developers should set their PendingIntents explicitly with the target component name. However, this is not the case in many real-world apps.
Previous research showed a few examples attacking a PendingIntent with the empty base Intent (i.e., no component and action), but they did not know how to exploit a PendingIntent with the implicit base Intent (i.e., no component yet with action) and commonly believed that it is also unexploitable like an explicit PendingIntent. Moreover, previous research did not identify common attack surfaces of retrieving PendingIntents. To address these two fundamental problems, we first discovered new surfaces of retrieving PendingIntents, including the widely-used Notifications, the SliceProvider commonly in the AOSP Settings app, and the rare MediaBrowserService. We then proposed a novel method of exploiting implicit PendingIntents for various privilege escalation, including information disclosure, data stealing, and even arbitrary code execution.
We further developed a static analysis tool based on control and data flows to identify potentially vulnerable PendingIntents at scale. We then manually inspected them and identified vulnerabilities in many high-profile and system apps, including the popular Twitter, Airbnb, Google Play Service apps, and SystemUI (CVE-2020-0114 and CVE-2021-0304), SettingsSliceProvider (CVE-2020-0188), BluetoothMediaBrowserService. Our vulnerability reporting triggered Google to introduce significant security changes about PendingIntents in Android 12 and assign new lint security rules in Android Studio.