4.2.2 创建/使用广播接收器 规则书
原书:Android Application Secure Design/Secure Coding Guidebook
译者:飞龙
遵循下列规则来发送或接受广播。
4.2.2.1 仅在应用中使用的广播接收器必须设置为私有(必需)
仅在应用中使用的广播接收器应该设置为私有,以避免意外地从其他应用接收任何广播。 它将防止应用功能滥用或异常行为。
仅在同一应用内使用的接收器,不应设计为设置意图过滤器。 由于意图过滤器的特性,即使通过意图过滤器调用同一应用中的私有接收器,其他应用的公共私有也可能被意外调用。
AndroidManifest.xml(不推荐)
<!-- Private Broadcast Receiver -->
<!-- *** POINT 1 *** Set the exported attribute to false explicitly. -->
<receiver
android:name=".PrivateReceiver"
android:exported="false" >
<intent-filter>
<action android:name="org.jssec.android.broadcast.MY_ACTION" />
</intent-filter>
</receiver>
请参阅“4.2.3.1 导出属性和意图过滤器设置的组合(对于接收器)”。
4.2.2.2 小心和安全地处理收到的意图(必需)
虽然风险因广播接收器的类型而异,但处理接收到的意图数据时,首先应该验证意图的安全性。 由于公共广播接收器从未指定的大量应用接收意图,它可能会收到恶意软件的攻击意图。 私有广播接收器将永远不会直接从其他应用接收任何意图,但公共组件从其他应用接收的意图数据,可能会转发到私有广播接收器。 所以不要认为收到的意图在没有任何验证的情况下,是完全安全的。 内部广播接收机具有一定程度的风险,因此还需要验证接收意图的安全性。
请参考“3.2 小心和安全地处理输入数据”。
4.2.2.3 验证签名权限是否由内部应用定义后,使用内部定义的签名权限(必需)
只接收内部应用发送的广播的内部广播接收器,应受内部定义的签名许可保护。 AndroidManifest.xml
中的权限定义/权限请求声明不足以保护,因此请参阅“5.2.1.2 如何使用内部定义的签名权限在内部应用之间进行通信”。 通过对receiverPermission
参数指定内部定义的签名权限来结束广播,需要相同的方式的验证。
4.2.2.4 返回结果信息时,清注意来自目标应用的结果信息泄露(必需)
通过setResult()
返回结果信息的应用的可靠性取决于广播接收器的类型。 对于公共广播接收器,目标应用可能是恶意软件,可能存在恶意使用结果信息的风险。 对于私有广播接收器和内部广播接收器,结果的目的地是内部开发的应用,因此无需介意结果信息的处理。
如上所述,当从广播接收器返回结果信息时,需要注意从目标应用泄漏的结果信息。
4.2.2.5 使用广播发送敏感信息时,限制能收到的接收器(必需)
广播是所创建的系统,用于向未指定的大量应用广播信息或一次通知其时间。 因此,广播敏感信息需要谨慎设计,以防止恶意软件非法获取信息。 对于广播敏感信息,只有可靠的广播接收器可以接收它,而其他广播接收器则不能。 以下是广播发送方法的一些示例。
- 方法是,通过使用显式意图,将广播仅仅发送给预期的可靠广播接收器,来固定地址。
- 当它发送给同一个应用中的广播接收器时,通过
Intent#setClass(Context, Class)
指定地址。 具体代码,请参阅“4.2.1.1 私有广播接收器 - 接收/发送广播”的示例代码部分。 - 当它发送到其他应用中的广播接收器时,通过
Intent#setClassName(String, String)
指定地址。 通过比较目标包中 APK 签名的开发人员密钥和白名单来发送广播,来确认允许的应用。 实际上下面的使用隐式意图的方法更实用。
- 当它发送给同一个应用中的广播接收器时,通过
- 方法是,通过将
receiverPermission
指定为内部定义的签名权限,并使可靠的广播接收器声明使用此签名权限,来发送广播。具体代码请参阅“4.2.1.3 内部广播接收器 - 接收/发送广播”的示例代码部分。 另外,实现这种广播发送方法,需要应用规则“4.2.2.3 在验证签名权限由内部应用定义之后,使用内部定义的签名权限”。
4.2.2.6 粘性广播中禁止包含敏感信息(必需)
通常情况下,广播由可用的广播接收器接收后会消失。 另一方面,粘性广播(以下粘性广播包括粘性有序广播)即使由可用的广播接收器接收也不会从系统中消失,并且能够由registerReceiver()
接收。 当粘性广播变得不必要时,可以随时用removeStickyBroadcast()
任意删除它。
由于在预设情况下,粘性广播被隐式意图使用。 具有指定receiverPermission
参数的广播无法发送。 出于这个原因,通过粘性广播发送的信息,可以被多个未指定的应用访问 - 包括恶意软件 - 因此敏感信息禁止以这种方式发送。 请注意,粘性广播在 Android 5.0(API Level 21)中已弃用。
4.2.2.7 注意不指定receiverPermission
的有序广播无法传递(必需)
不指定receiverPermission
参数的有序广播,可以由未指定的大量应用接收,包括恶意软件。 有序广播用于接收来自接收器的返回信息,并使几个接收器逐一执行处理。 广播按优先顺序发送给接收器。 因此,如果高优先级恶意软件先接收广播并执行abortBroadcast()
,则广播将不会传送到后面的接收器。
4.2.2.8 小心并安全地处理来自广播接收器的返回的结果数据(必需)
基本上,考虑到接收结果可能是攻击数据,结果数据应该被安全地处理,尽管风险取决于返回结果数据的广播接收器的类型。
当发送方(源)广播接收器是公共广播接收器时,它从未指定的大量应用接收返回数据。 所以它也可能会收到恶意软件的攻击数据。 当发送方(源)广播接收器是私有广播接收者时,似乎没有风险。 然而,其他应用接收的数据可能会间接作为结果数据转发。 因此,如果没有任何验证,结果数据不应该被认为是安全的。 当发送方(源)广播接收器是内部广播接收器时,它具有一定程度的风险。 因此,考虑到结果数据可能是攻击数据,应该以安全的方式处理它。
请参考“3.2 小心和安全地处理输入数据”。
4.2.2.9 提供二手素材时,素材应该以相同保护级别提供(必需)
当由权限保护的信息或功能素材被二次提供给其他应用时,有必要通过声明与目标应用相同的权限来维持保护标准。 在 Android 权限安全模型中,权限仅管理来自应用的受保护素材的直接访问。 由于这些特点,所得素材可能会被提供给其他应用,而无需声明保护所需的权限。 这实际上与重新授权相同,因为它被称为重新授权问题。 请参阅“5.2.3.4 重新授权问题”。