Android安全开发之Provider组件安全
作者:伊樵、呆狐@阿里聚安全
1 Content Provider组件简介
Content Provider组件是Android应用的重要组件之一,管理对数据的访问,主要用于不同的应用程序之间实现数据共享的功能。Content Provider的数据源不止包括SQLite数据库,还可以是文件数据。通过将数据储存层和应用层分离,Content Provider为各种数据源提供了一个通用的接口。
创建一个自己的Content Provider需要继承自ContentProvider抽象类,需要重写其中的onCreate()、query()、insert()、update()、delete()、getType()六个抽象方法,这些方法实现对底层数据源的增删改查等操作。还需在AndroidManifest文件注册Content Provider,注册时指定访问权限、exported属性、authority属性值等。
其它APP使用ContentResolver对象来查询和操作Content Provider,此对象具有Content Provider中同名的方法名。这样其他APP接就可以访问Content Provider对应的数据源的底层数据,而无须知道数据的结构或实现。
如何定位到具体的数据?
采用Content Uri,一个Content Uri如下所示:
content://com.jaq.providertest.friendsprovider/friends
它的组成一般分为三部分:
- (1)content://:作为 content Uri的特殊标识(必须);
- (2)权(authority):用于唯一标识这个Content Provider,外部访问者可以根据这个标识找到它;在AndroidManifest中也配置的有;
- (3)路径(path): 所需要访问数据的路径,根据业务而定。
这些内容就不具体展开详谈了,详见参考[1][4]。
2 风险简介
如果在AndroidManifest文件中将某个Content Provider的exported属性设置为true,则多了一个攻击该APP的攻击点。如果此Content Provider的实现有问题,则可能产生任意数据访问、SQL注入、目录遍历等风险。
2.1 私有权限定义错误导致数据被任意访问
私有权限定义经常发生的风险是:定义了私有权限,但是却根本没有定义私有权限的级别,或者定义的权限级别不够,导致恶意应用只要声明这个权限就能够访问到相应的Content Provider提供的数据,造成数据泄露。
以公开的乌云漏洞WooYun-2014-57590为例:
某网盘客户端使用了自己的私有权限,但是在AndroidManifest中却没有定义私有权限,其它APP只要声明这个权限就能访问此网盘客户端提供的Provider,从而访问到用户数据。
在网盘客户端的AndroidManifest中注册Provider时,声明了访问时需要的读写权限,并且权限为客户端自定义的私有权限:
但是在AndroidManifest中却没有见到私有权限“com.huawei.dbank.v7.provider.DBank.READ_DATABASE”和“com.huawei.dbank.v7.provider.DBank.WRITE_DATABASE”的定义:
反编译客户端后查看到的URI,根据这些可以构造访问到Provider的URI:
编写POC