在Android系统开发中,Service是一个重要的组成部分。如果现在某些程序中的某部分操作是很耗时的,那么可以将这些程序定义在Service中,这样就可以在后台运行,也可以在不显示界面的形式下运行,即,Service实际上就是相当于一个没有图形界面的Activity程序,而且当用户执行某些操作需要进行跨进程访问的时候也可以使用Service来完成。
Service的分类
本地服务(Local)
该服务依附在主进程上,不是独立的进程。本地服务在一定程度上节约了资源,由于是在同一进程因此不需要IPC,也不需要AIDL。相应bindService会方便很多。主进程被Kill后,服务便会终止。
远程服务(Remote)
该服务是独立的进程,对应进程名格式为所在包名加上你指定的android:process字符串。由于是独立的进程,因此在Activity所在进程被Kill的时候,该服务依然在运行,不受其他进程影响,有利于为多个进程提供服务具有较高的灵活性。但由于独立的进程,会占用一定资源,并且使用AIDL进行IPC稍微麻烦一点。一些提供系统服务的Service通常是常驻的。
Service组件已知产生的安全问题
权限提升
Service劫持
拒绝服务
消息伪造
安全问题案例
以拒绝服务问题为例,常见的拒绝服务分为两种:
1.java.lang.NullPointerException 空指针异常导致的拒绝服务 ClassCastException
2.类型转换异常导致的拒绝服务
POC内传入畸形数据即可引发crash,捕获异常即可修复。
研发人员该如何预防
不同Service的安全描述
私有Service:不能被其他应用调用,相对安全
公共Service:可以被任意应用调用
可信Service:只能被可以信任的应用调用
内部Service:只能被内部应用调用
intent-filter与exported属性配置方法
私有service不定义intent-filter并且设置exported为false
公开的service设置exported为true,intent-filter可以定义或者不定义
内部或可信service设置exported为true,intent-filter不定义
安全研发建议
应用内部使用的Service应设置为私有
针对Service接收到的数据应该验证并谨慎处理
内部Service需要使用签名级别的protectionLevel来判断是否未内部应用调用
不建议在onCreate方法调用的时候决定是否提供服务,建议在onStartCommand、onBind、onHandleIntent等方法被调用的时候做判断
使用显示意图只针对有明确服务需求的情况 尽量不发送敏感信息 可信任的Service需要对第三方可信公司的app签名做效验