The ContentProvider class provides a mechanism for managing and sharing data with other applications. When sharing a provider’s data with other apps, access control should be carefully implemented to prohibit unauthorized access to sensitive data.

There are three ways to limit access to the content provider:

  • 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,

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

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,

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

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

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

Proof of Concept

The following code shows how this could be exploited:

// 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:

<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

medium

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

4.3. Creating/using content providers
4.3.1.1. Creating/using private content providers
4.3.1.3. Creating/using partner content providers
4.3.1.4. Creating/using in-house content providers
4.3.1.5. Creating/using temporary permit content providers
4.3.2.1. Content provider that Is used only in an application cannot be created in android 2.2 (API Level 8) or earlier
4.3.2.2. Content provider that is used only in an application must be set as private
4.3.2.4. Use an in-house defined signature permission after verifying that it is defined by an in-house application

Bibliography

[JSSEC 2014]

 4.3. Creating/Using a Content Provider (2013/4/1 edition)


6 Comments

  1. The title is ambiguous.  Should it be: "Limit the accessibility of an app's sensitive content provider"?

    1. Unknown User (lflynn)

      Yes. Changed it, thanks.

  2. Any updates on the Restrict Access?

  3. Unknown User (lflynn)

    Robert C. Seacord: I wish I had time to, but research is taking all my cycles right now. Your editing help to complete this rule would be very welcome! (smile)

    1. I would, but Mark Sherman took away my edit privileges.