安卓开发开发规范手册V1.0
之前发布过一份Web安全开发规范手册V1.0,看到收藏文章的读者挺多,发现整理这些文档还挺有意义。
最近周末抽了些时间把之前收集关于安卓安全开发的资料也整理了一下,整理出一份安卓安全开发手册,大部分内容都是在一些博客看到各位师傅的分享。
一、manifest文件安全
1.1 禁止PermissionGroup的属性为空
PermissionGroup可以对permission进行一个逻辑上的分组。如果PermissionGroup的属性为空,会导致权限定义无效,且其他app无法使用该权限。
开发建议
设置PermissionGroup属性值或者不使用PermissionGroup。
1.2 系统权限确认
App如果使用一些系统限制权限,诸如android.permission.WRITE_SECURE_SETTINGS和android.permission.INSTALL_PACKAGES,则该app应该是设备自带的系统或google自带的app,并且应该放置在/system/app目录下。否则就是一个恶意app。
App使用下述权限,则该app有较高权限,要谨慎使用。
android.permission.MOUNT\_FORMAT\_FILESYSTEMS,
android.permission.MOUNT\_UNMOUNT\_FILESYSTEMS,
android.permission.RESTART\_PACKAGES。
开发建议
根据业务需求,如非必要,移除该权限。
1.3 protectionLevel属性设置
由于对app的自定义permission的protectionLevel属性设置不当,会导致组件(如:content provider)数据泄露危险。最好的权限设置应为signature或signatureOrSystem,进而避免被第三方应用利用。
开发建议
注意使用signature或signatureOrSystem防止其他app注册或接受该app的消息,提高安全性。
1.4 合理设置sharedUserId权限
通过sharedUserId,可以让拥有同一个User Id的多个apk运行在同一个进程中,互相访问任意资源。将sharedUserId设置为android.uid.system,可以把app放到系统进程中,app将获得极大的权限。如果app同时有master key漏洞,容易导致被root。
开发建议
合理设置软件权限。
1.5 设置allowBackup为false
当这个标志被设置成true或不设置该标志位时,应用程序数据可以备份和恢复,adb调试备份允许恶意攻击者复制应用程序数据。
开发建议
设置AndroidManifest.xml的android:allowBackup标志为false。
影响范围
API >= 8
1.6 禁止Debuggable为true
在AndroidManifest.xml中定义Debuggable项,如果该项被打开,app存在被恶意程序调试的风险,可能导致泄露敏感信息等问题。
开发建议
显示的设置AndroidManifest.xml的debuggable标志为false。
二、组件安全
2.1 合理设置导出Activity、activity-alias、service、receiver
Activity、activity-alias、service、receiver组件对外暴露会导致数据泄露和恶意的dos攻击。
开发建议
1.最小化组件暴露。对不会参与跨应用调用的组件添加android:exported=false属性。
2.设置组件访问权限。对跨应用间调用的组件或者公开的receiver、service、activity和activity-alias设置权限,同时将权限的protectionLevel设置为signature或signatureOrSystem。
3.组件传输数据验证。对组件之间,特别是跨应用的组件之间的数据传入与返回做验证和增加异常处理,防止恶意调试数据传入,更要防止敏感数据返回。
2.2 Contentprovider信息泄露风险
provider组件导出可能会带来信息泄露隐患。api level在17以下的所有应用的android:exported属性默认值为true,17及以上默认值为false。
开发建议
1.最小化组件暴露。对不会参与跨应用调用的组件添加android:exported=false属性。
2.设置组件访问权限。对导出的provider组件设置权限,同时将权限的protectionLevel设置为signature或signatureOrSystem。
3.由于Contentprovider无法在2(API-8)申明为私有。故建议将min sdk设为8以上。
影响范围
api level在17以下的所有应用的android:exported属性默认值为true,17及以上默认值为false。
2.3 严格过滤openFile对uri访问
该漏洞由于Content provider组件暴露,没有对Content provider组件访问权限进行限制且对Uri路径没有进行过滤,攻击者通过Content provider实现的OpenFile接口进行攻击,如通过../的方式访问任意的目录文件,造成隐私泄露。
开发建议
1.将不必要导出的Content provider设置为不导出
2.由于Android组件Content provider无法在Android 2.2(即API Level 8)系统上设为不导出,因此如果应用的Content provider不必要导出,阿里聚安全建议声明最低SDK版本为8以上版本;
3.由于API level 在17以下的所有应用的android:exported属性默认值都为,因此如果应用的Content provider不必要导出,阿里聚安全建议显示设置注册的Content provider组件的android:exported属性为false;
4.去除没有必要的penFile()接口
5.如果应用的Content provider组件没有必要实现penFile()接口,阿里聚安全建议移除该Content provider的不必要的penFile()接口。
6.过滤限制跨域访问,对访问的目标文件的路径进行有效判断
7.使用decode()先对Content Query Uri进行解码后,再过滤如可通过../实现任意可读文件的访问的Uri字符串;
8.设置权限来进行内部应用通过Content provider的数据共享
9.使用签名验证来控制Content provider共享数据的访问权限,如设置protectionLevel=signature或signatureOrSystem;
10.公开的content provider确保不存储敏感数据
11.提供asset文件时注意权限保护
2.4 使用显式Intent 调用bindService()
创建隐式Intent 时,Android 系统通过将Intent 的内容与在设备上其他应用的清单文件中声明的Intent 过滤器进行比较,从而找到要启动的相应组件。如果Intent 与Intent 过滤器匹配,则系统将启动该组件,并将其传递给对象。如果多个Intent 过滤器兼容,则系统会显示一个对话框,支持用户选取要使用的应用。
为了确保应用的安全性,启动Service 时,请始终使用显式Intent,且不要为服务声明Intent 过滤器。使用隐式Intent 启动服务存在安全隐患,因为您无法确定哪些服务将响应Intent,且用户无法看到哪些服务已启动。从Android 5.0(API 级别21)开始,如果使用隐式Intent 调用bindService(),系统会抛出异常。
开发建议
为了确保应用的安全性,启动 Service 时,请始终使用显式 Intent,且不要为服务声明 Intent 过滤器。使用隐式 Intent 启动服务存在安全隐患,因为您无法确定哪些服务将响应Intent,且用户无法看到哪些服务已启动。从 Android 5.0(API 级别 21)开始,如果使用隐式 Intent 调用