Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restrict access to content provider

I did not find a post which ask for the same restriction as me.

I have an application which provides a content provider (call it main application) to other applications (call them client applications). I want restrict the access to the content provider from the client applications for support only the insert and maybe query methods.

What I do not want:

  • Make the content provider private because the main goal is to provide a database to client applications.
  • Restrict the access with signatures of client applications because anyone must be able to write a client application which use the main application platform.

The most obvious solution I see is to write two content provider, one with full access private of the main application, and one restricted public. But I think this is definitely not a proper way.

According to this Google groups post, I am thinking to use Binder.getCallingUid() in the content provider calls to detect if the call comes from the main application or not. So I can do nothing in update and delete methods if the call does not come from the main application.

How I can get the main application UID to compare? And if it is possible, is this solution secure?

Thanks for your advice.

like image 638
FabiF Avatar asked Aug 31 '12 09:08

FabiF


People also ask

What is content provider access?

A content provider manages access to a central repository of data. A provider is part of an Android application, which often provides its own UI for working with the data. However, content providers are primarily intended to be used by other applications, which access the provider using a provider client object.

What is the main purpose of a content provider?

Content providers can help an application manage access to data stored by itself, stored by other apps, and provide a way to share data with other apps. They encapsulate the data, and provide mechanisms for defining data security.

What is the purpose of content provider in Android?

Content providers are one of the primary building blocks of Android applications, providing content to applications. They encapsulate data and provide it to applications through the single ContentResolver interface. A content provider is only required if you need to share data between multiple applications.

What is content provider authority?

A content URI is a URI that identifies data in a provider. Content URIs include the symbolic name of the entire provider (its authority) and a name that points to a table or file (a path).


1 Answers

Define a permission like below with protectionLevel signature, this WRITE permission will restricted to only apps which are signed with same private key

<permission android:name="com.yourapp.WRITE.PERMISSION"
    android:protectionLevel="signature"
        android:label="@string/permission_label"
        android:description="@string/permission_desc">
</permission>

<permission android:name="com.yourapp.READ.PERMISSION"
        android:label="@string/permission_label"
        android:description="@string/permission_desc">
</permission>

Then in contentprovider tag use read and write permission tags. You can either enforce read permission or you could altogether remove it

android:readPermission="com.yourapp.READ.PERMISSION"
android:writePermission="com.yourapp.WRITE.PERMISSION"

So only apps that are signed by same signature can use your content provider

Edit:

Maybe you could use this

 private Collection<String> getCallingPackages() {
     int caller = Binder.getCallingUid();
     if (caller == 0) {
         return null;
     }
     return Lists.newArrayList(mContext.getPackageManager().getPackagesForUid(caller));
 }

And check if your packagename is present in this list. I think it is safe

like image 93
nandeesh Avatar answered Oct 19 '22 17:10

nandeesh