OWASP 类别: MASVS-CODE: 代码质量
概述
使用 PendingIntent.getCreator*()
或 PendingIntent.getTarget*()
来确定是否信任 PendingIntent 的发件人会造成漏洞风险。
PendingIntent.getCreator*()
或 PendingIntent.getTarget*()
会返回 PendingIntent 的创建者,它并不总是与发件人匹配。创建者可能是可信的,但发件人 **绝不** 应该被信任,因为发件人可能是使用各种机制获取了另一个应用程序的 PendingIntent 的恶意应用程序,例如
- 来自
NotificationListenerService
- 作为易受攻击的应用程序一部分的合法用例。
使用 PendingIntent.getCreator*()
或 PendingIntent.getTarget*()
的合法用例示例是显示将由 PendingIntent 启动的应用程序的图标。
影响
由于查询(并信任)了创建者,因此信任 PendingIntent 的发件人会导致漏洞。如果应用程序根据创建者信任 PendingIntent 的发件人,然后共享其身份验证或授权逻辑,那么无论何时 PendingIntent 的发件人都是恶意应用程序,这将导致身份验证绕过,甚至可能导致远程代码执行,具体取决于易受攻击的应用程序代码的实现方式。基于无效的、不可信的输入。
缓解措施
区分发件人和创建者
在接收 PendingIntent 时执行的任何类型的身份验证或授权逻辑,都不能基于使用 PendingIntent.getCreator*()
或 PendingIntent.getTarget*()
识别的 PendingIntent 的创建者相关的假设。
使用替代方法验证调用者
如果您需要对调用者进行身份验证,而不是使用 PendingIntent,您应该使用 Service 或 ContentProvider——两者都允许在分发传入 IPC 的上下文中使用 Binder.getCallingUid() 获取调用者 UID。稍后可以使用 PackageManager.getPackagesForUid() 查询 UID。
另一种方法,从 API 级别 34 开始可用,是使用 BroadcastReceiver.getSentFromUid() 或 BroadcastReceiver.getSentFromPackage(),如果发送者选择在使用 BroadcastOptions.isShareIdentityEnabled() 广播时共享身份。
您应该始终检查调用包是否具有预期的签名,因为侧载包的包名可能与 Play 商店中的包名重叠。