Pending Intent 的发送方

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 起可用)是,如果发送方在使用 BroadcastOptions.isShareIdentityEnabled() 进行广播期间选择了共享身份,则可以使用 BroadcastReceiver.getSentFromUid()BroadcastReceiver.getSentFromPackage()

您应始终检查调用方软件包是否具有预期的签名,因为通过侧载安装的软件包可能与 Play 商店中的软件包名称重叠。

资源