9

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.

FabiF
  • 2,796
  • 2
  • 18
  • 27
  • If I understand correctly, the application containing the content provider component should be the only one having write access. In that why can't it use that functionality without going through the Content Provider interface? In that case the Content provider would only support the query interface. – Sameer Aug 31 '12 at 10:03
  • Unfortunately, the main access needed by client applications is the insertion. So they need also having the write access. But you are right the main application is not required to use content provider but it will increase too much complexity and maintainability. – FabiF Aug 31 '12 at 10:22
  • well, still same point. the main application can do inserts, updates and deletes directly without going through the Content Provider interface. The Content Provider only provides insert and query interface. – Sameer Aug 31 '12 at 10:28
  • Yes your still right on this point, I have edited my comment above. – FabiF Aug 31 '12 at 10:33

1 Answers1

10

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

nandeesh
  • 24,740
  • 6
  • 69
  • 79
  • I'm aware of this solution but in my case, client applications have to be able to *insert* data, so they also need having the write access. – FabiF Aug 31 '12 at 10:31
  • what do you want to restrict then? only few client applications by packagename? – nandeesh Aug 31 '12 at 10:43
  • if your own app needs the data do it through sqlitedbhelper and give reduced access through contentprovider – nandeesh Aug 31 '12 at 10:45
  • I want forbid all *update* and *delete* requests which not come from the main application. – FabiF Aug 31 '12 at 10:46
  • Yes but even if main application is not required to use content provider, it will increase too much complexity and maintainability. So at this time the only option is to create two content providers. – FabiF Aug 31 '12 at 10:48
  • Thank you! It sounds quite clean and secure. – FabiF Aug 31 '12 at 13:07