待处理 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 及更高版本可用)是使用 BroadcastReceiver.getSentFromUid()BroadcastReceiver.getSentFromPackage(),前提是发送者在使用 BroadcastOptions.isShareIdentityEnabled() 广播时选择共享身份。

您应始终检查调用程序包是否具有预期的签名,因为侧载程序包的程序包名称可能与 Play 商店中的程序包名称重叠。

资源