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”,例如:
如果ContentProvider被設定為Public,那麼儲存在ContentProvider裡面的資料就可以被其他app訪問到。因此,設計上必須保證只公開了非保密的資訊。
[Private]
在AndroidManifest.xml檔案中聲明android:exported屬性,可以將ContentProvider設定為Private的。從Android API Level 17及之後的版本,ContentProvider預設是Private的,不需要顯式聲明,例如:
如果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是公開的。
[概念驗證]
下面的代碼展示了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 providerUri 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”
——歡迎轉載,請註明出處 http://blog.csdn.net/asce1885 ,未經本人同意請勿用於商業用途,謝謝——