在安全审查中关于组件导出风险是一种常见问题,不同组件都有可能遇到这种问题,而且从一定角度来看的话,如果涉及到三方业务,基本处于无法解决的场景,所以我们需要说明为何无法避免这种风险
组件导出风险能不能规避?能不能解决?
如果你的组件风险是由 exported
属性所引起,那么可以规避,也可以解决,只要将 exported
设置为 false
即可; 这样外部就无法调用项目内组件了,自然就避免了风险的产生,同时带来了一些不太好的结果,例如业务出错、功能缺失等等,毕竟 很多项目内集成的三方平台SDK都是需要 exported
所附带的权限的!
最终结果:当 组件导出风险
遇到三方业务时,很多时候我们可能无法规避这类型风险!
雨
- 基础分析
- 那些无法解决的风险场景
- Activity 组件导出风险
- Service 组件导出风险
- Broadcast Receiver组件导出风险
- 定义权限、保护组件
基础分析
组件导出风险一般都是由
android:exported
属性引起的,如果我们在AndroidManifest
对应组件内声明了android:exported=true
,意味着允许让外部组件启动这个组件;反之,则不允许让外部组件启动这个组件;
初步搜索后,AI已经给出了部分参考答案,简单看一下就好(解决方式未尝试,不确定是否可用)
其实当你已经将 android:exported
设置为 true
时,已经证明该组件因业务需要确实需要被外部调用,这种场景如果是项目内我方业务的话,可以参考 权限过滤
、intent-filter
过滤方式(个人感觉这种方式只是在内部做了限制保护,从安全检查的角度来看可能当你android:exported
设置为 true
时就已经存在风险了,并不关注你内部做了何限制…)
如果android:exported
设置了false
,又在外部试图启动这个Activity,则会发生程序崩溃,报异常,例如:
java.lang.SecurityException: Permission Denial: starting Intent
常见组件可以参考Android四大组件
- 活动(Activity):用于表现功能,是用户操作的可视化界面,它为用户提供了一个完成操作指令的窗口;
- 服务(Service):后台运行服务,不提供界面呈现;
- 广播接受者(Broadcast Receive):用于接收广播;
- 内容提供者(Content Provider):支持多个应用中存储和读取数据,相当于数据库。
exported
在不同场景下默认值也有所不同
关于
exported
属性还是挺关键的,参考自 Android 组件导出风险及防范
Activity、Service、Broadcast Receive
中 exported
默认值
- 没有
intent filter
时,默认为false
- 有
intent filter
时,默认为true
Content Provider
中 exported
默认值
- 当
minSdkVersion
或者targetSdkVersion
小于16时,默认为true
- 大于17时,默认为
false
那么组件导出的风险到底有哪些?
- Activity :可能导致登录界面被绕过、拒绝服务攻击、程序界面被第三方恶意调用等风险
- Service :能被系统或者第三方的App直接调出并使用,可能导致拒绝服务攻击,程序功能被第三方恶意调用等风险
- Broadcast Receiver :对外部事件进行过滤接收,并根据消息内容执行响应,如果设置了导出权限,可能被系统或者第三方的App直接调出并使用。同时可能导致敏感信息泄露、登录界面被绕过等风险。
- Content Provider :可能导致程序内部的敏感信息泄露,数据库SQL注入等风险
那些无法解决的风险场景
像以下这些场景的导出风险从一定角度来说是无法解决的,我们只需反馈给安全人员因为什么业务原因,无法避免此项风险
Activity 组件导出风险
检测方式
- 反编译提取应用的
AndroidManifest
文件并解析获取所有注册的Activity组件
- 查看
是否显式的设置可导出信息或者配置了意图过滤器
微博分享SDK(配置)
解决方式:像这种三方平台组件,一般都无法解决,主要是因为涉及到已有业务,除非剥离业务,但这也不现实~ 所以只需要反馈到安全机构因XX业务原因,无法规避这类型风险
Service 组件导出风险
检测方式
- 反编译提取应用的
AndroidManifest
文件并解析 - 获取所有注册的
Service
组件,查看是否显式的设置了可导出信息或者配置了意图过滤器
魅族推送、通知服务(配置)
解决方式:像这种三方平台组件,一般都无法解决,主要是因为涉及到已有业务,除非剥离业务,但这也不现实~ 所以只需要反馈到安全机构因XX业务原因,无法规避这类型风险(图中的就是微博分享的业务功能
)
Broadcast Receiver组件导出风险
检测方式
- 反编译提取应用的
AndroidManifest
文件并解析 - 获取所有注册的
Receiver
组件,查看是否显式的设置了可导出信息或者配置了意图过滤器
极光推送-小米推送相关业务(配置)
定义权限、保护组件
权限过滤中涉及到了权限定义,参考 Android 组件导出风险及防范 做个笔记
Android提供了自定义权限的能力,应用可以定义自己的权限,如在清单文件中自定义一个 permission
<permission
android:label="允许打开WebActivity页面权限"
android:name="com.littlejerk.sample.permission.WEB"
android:protectionLevel="signature" />
- label:权限的描述
- name:该权限的名称,使用该权限时通过名称来指定使用的权限
- protectionLevel:该权限受保护的等级,这很重要,它有三个等级
signature
:签名级别权限,即权限的定义方和注册方必须具有相同的签名才有效system
:系统级别权限,即权限的定义方和注册方必须为系统应用signatureOrSystem
:同签名或系统应用,上述二者具备其一即可
用刚定义的权限来保护暴露的组件(activity)
<!--调用方必须申请此权限-->
<uses-permission android:name="com.littlejerk.sample.permission.WEB"/>
<activity
android:permission="com.littlejerk.sample.permission.WEB"
android:name=".other.WebActivity">
<intent-filter>
<action android:name="com.littlejerk.sample.action.VIEW_URL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
个人思考:在项目中看到了 push模块
的权限声明、授权,有可能是集成三方平台时平台自己做的权限定义,如果从这方面来看平台可能已经尽可能降低了组件导出风险,至少不会造成二次导出风险