待处理 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 的创建者是使用 PendingIntent.getCreator*()
或 PendingIntent.getTarget*()
标识的。
使用其他方式验证调用方
如果您需要对调用方进行身份验证,则应使用 Service 或 ContentProvider,而不是 PendingIntent。当您处于调度传入 IPC 的上下文中时,这两者都允许使用 Binder.getCallingUid() 获取调用方 UID。稍后可以使用 PackageManager.getPackagesForUid() 查询 UID。
另一种方法(从 API 级别 34 开始提供)是使用 BroadcastReceiver.getSentFromUid() 或 BroadcastReceiver.getSentFromPackage()(如果发送方选择在广播期间使用 BroadcastOptions.isShareIdentityEnabled() 共享身份)。
您应始终检查调用方软件包是否具有预期签名,因为旁加载的软件包的软件包名称可能与 Play 商店中的软件包名称重叠。
资源
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-07-27。
[null,null,["最后更新时间 (UTC):2025-07-27。"],[],[],null,["# Sender of Pending Intents\n\n\u003cbr /\u003e\n\n**OWASP category:** [MASVS-CODE: Code Quality](https://mas.owasp.org/MASVS/10-MASVS-CODE)\n\nOverview\n--------\n\nUsing [`PendingIntent.getCreator*()`](/reference/android/app/PendingIntent#public-methods_1) or [`PendingIntent.getTarget*()`](/reference/android/app/PendingIntent#public-methods_1) to determine whether to trust a PendingIntent's sender creates an\nexploitation risk.\n\n[`PendingIntent.getCreator*()`](/reference/android/app/PendingIntent#public-methods_1) or\n[`PendingIntent.getTarget*()`](/reference/android/app/PendingIntent#public-methods_1) returns the PendingIntent's\ncreator, which does not always match its sender. The creator may be trusted, but\nthe sender should **never** be trusted, as the sender might be a malicious app\nthat acquired another app's PendingIntent using a variety of mechanisms, for\nexample:\n\n- from [`NotificationListenerService`](/reference/android/service/notification/NotificationListenerService)\n- legitimate use cases that are part of the vulnerable app.\n\nAn example of a legitimate use of [`PendingIntent.getCreator*()`](/reference/android/app/PendingIntent#public-methods_1) or [`PendingIntent.getTarget*()`](/reference/android/app/PendingIntent#public-methods_1) would be to show\nthe icon of the app that will be started by the PendingIntent.\n\nImpact\n------\n\nTrusting a PendingIntent's sender because you queried (and trust) the creator\ncan lead to vulnerabilities. If an app trusts the PendingIntent's sender based\non its creator, and then shares its authentication or authorization logic, then\nwhenever the PendingIntent's sender is a malicious app, this would lead to an\nauthentication bypass or potentially even remote code execution based on\ninvalidated, untrusted input, depending on the implementation of the vulnerable\napplication's code.\n\nMitigations\n-----------\n\n### Distinguish between sender and creator\n\nAny type of authentication or authorization logic performed when receiving a\nPendingIntent must not be based on assumptions regarding the PendingIntent's\ncreator identified using either [`PendingIntent.getCreator*()`](/reference/android/app/PendingIntent#public-methods_1)\nor [`PendingIntent.getTarget*()`](/reference/android/app/PendingIntent#public-methods_1).\n\n### Use alternative ways to validate callers\n\nIf you need to authenticate the caller, instead of using PendingIntent, you\nshould use a Service or ContentProvider -- both allow fetching the caller UID\nwith [Binder.getCallingUid()](/reference/android/os/Binder#getCallingUid()) when you are in the context of dispatching an\nincoming IPC. The UID can be queried later by using\n[PackageManager.getPackagesForUid()](/reference/android/content/pm/PackageManager#getPackagesForUid(int)).\n\nAnother approach, available from API level 34, would be to use\n[BroadcastReceiver.getSentFromUid()](/reference/android/content/BroadcastReceiver#getSentFromUid()) or\n[BroadcastReceiver.getSentFromPackage()](/reference/android/content/BroadcastReceiver#getSentFromPackage()) if the sender opted in to sharing\nidentity during broadcast using [BroadcastOptions.isShareIdentityEnabled()](/reference/android/app/BroadcastOptions#isShareIdentityEnabled()).\n\nYou should always check if the calling package has the expected signature, as\nsideloaded packages can have package names overlapping with ones from the Play\nStore.\n\nResources\n---------\n\n- [Pending Intent](/reference/android/app/PendingIntent)"]]