您的利用是否提供了这样的 Service,当触发某些操作时,作为回调它会启动另一个利用的 Activity
?
比方,一个 Intent
承受了另一个 Intent
作为它的 Extra 参数,并将其作为参数通过 startActivity()
进行调用。
您是否晓得,这种做法会让您的利用变得容易被攻打?
接下来,我将会解释应用这种办法带来的问题,并提供一个解决方案来让您的利用在更平安的前提下实现雷同性能。
问题
咱们冀望这种类型的交互流程如下图所示:
流程图展现了一个启动回调 activity 的 Intent 如何作为一个扩大数据增加到一个启动 Service 的 Intent 中,而后应用此 Intent 启动回调 Activity
如上图所示,Client 利用为 ClientCallbackActivity
创立了一个 Intent
并将其作为 extra 增加到启动 Provider 利用的 ApiService
组件的 Intent
中。解决完启动 ApiService 的申请之后,Provider 利用应用 Client 利用创立的 Intent
去启动 ClientCallbackActivity
。
❗️这里须要留神的是 Provider 利用正在应用它本人的利用 Context
去调用 startActivity()
办法。这样的调用形式会产生两个不良的结果:
- 因为
ClientCallbackActivity
是被 Provider 利用从内部启动的,在清单文件中必须将其标识为exported
,这样不仅 Provider 利用能够启动 ClientCallbackActivity,设施上任何其余的利用也都能够启动。 - 传递给 ApiService 的嵌套
Intent
能够被用来启动 Provider 利用内的任意 Activity,包含公有的,可能蕴含敏感信息的或者非导出的 Activity。
考虑一下这种场景: 如果调用方利用提供的 Intent
并不是启动调用方利用内的 Activity (比方 ClientCallbackActivity
),而是去启动 Provider 利用中的公有 Activity,可能会产生什么?
流程图展现了,如何通过精心构建出的 Intent 来启动 Provider 利用中的 ApiSensitiveActivity,即便它没有被标记为 exported,并且也不应该被其余利用启动。
因为应用了嵌套 Intent
,Provider 利用很难防备其余利用去启动利用外部公有的、有潜在敏感信息的 Activity。因为 Provider 利用间接应用 Intent 调用 startActivity() 办法,即便 ApiSensitiveActivity
未被标记为 exported,依然能够启动它。
解决方案: PendingIntent
解决方案很简略: 与其承受一个 Intent
,Provider 利用能够变为承受 PendingIntent
。Provider 利用承受 PendingIntent 参数,不承受 Intent 参数。
PendingIntent
和 Intent
之间的区别在于 PendingIntent
只有在其被创立的 context 能力被解决。
流程图展现了如何从创立 PendingIntent 的 context 中对其进行解决,以避免攻击者调用 Provider 利用中未被标记为 exported 的 Activity。
因为回调是以 PendingIntent
的形式提供的,当 Provider 利用对其调用 send()
办法时,startActivity()
办法的调用会被当作是从 Attacker 利用发动的,因为 Attacker 利用并没有启动 ApiSensitiveActivity
的权限,零碎会阻止此次调用,避免 ApiSensitiveActivity
被启动。
这样的做法对于 Provider 利用来说当然是有益处的,那对于咱们本人的利用呢?因为咱们提供的是 PendingIntent
,当初就能够将 ClientCallbackActivity
设置为公有的,非导出的 Activity 组件。这样的变动使得 Client 和 Provider 利用都领有了更好的安全性。
如果您相熟对于 notification 解决或 alarm 治理的 API,您会留神到,它们应用了 PendingIntents
去激活某项操作或者在利用内进行 alarm 提醒。PendingIntents
能够认为是被创立它的利用所解决的,这就是零碎应用 PendingIntents
而不是一般 Intent 的起因。
总结
应用 Intent
作为实现对 Activity
回调的机制,无论对 Provider 还是 Client 利用,都会给其带来平安危险。这是因为 Intent 总是在其被调用的利用内的 Context
中被解决的。这个 Context
有可能会启动 Provider 利用中任意非导出 Activity,并且还会强制 Client 利用导出须要承受回调的 Activity。
相同 PendingIntents
是在其被创立的 Context
中被解决,这不仅能够让 Provider 利用自在地应用它们,而不必暴露出任何非导出 Activity,还能够让 Client 利用指定任意的 Activity (包含非导出的) 来承受回调。