待处理意图的发件人

OWASP 类别: MASVS-CODE: 代码质量

概述

使用 PendingIntent.getCreator*()PendingIntent.getTarget*() 来确定是否信任 PendingIntent 的发件人会造成漏洞风险。

PendingIntent.getCreator*()PendingIntent.getTarget*() 会返回 PendingIntent 的创建者,它并不总是与发件人匹配。创建者可能是可信的,但发件人 **绝不** 应该被信任,因为发件人可能是使用各种机制获取了另一个应用程序的 PendingIntent 的恶意应用程序,例如

使用 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 商店中的包名重叠。

资源