What, in your opinion, data access security mechanisms should be used when implementing a content provider? And what is not necessary, but possible? We consider a scenario in which there will be both applications with limited access granted to them (only reading a certain part of the data) and the main application manager.

  • one
    Very interesting question, I will answer a little later - after colleagues express themselves - Barmaley
  • Quite a curious manifestation of politeness :) I will be glad to hear an informed opinion. - pozharnik16
  • @Barmaley: question under threat of closure, create at least a response blank) - Nick Volynkin
  • @NickVolynkin has compiled a blank. Well, really there is no time to write. NG on the nose - everything burns at work ... - Barmaley
  • @Barmaley: likewise with work. Even if you remove the disc, we can restore it. - Nick Volynkin

2 answers 2

Since the TS spoke about the password manager, I would venture to make 2 assumptions:

  1. DB content is encrypted
  2. The descrambler key is generated when the user logs into the program.

These are common places when creating a password manager (I speak as a person who has written several such programs).

Now let's turn to the ContentProvider - they are either exported or not exported - the difference between them is that exported is available to an external program - in this case, the ContentProvider acts as a kind of port that is ContentProvider out by the program. Depending on the situation, the port can either be written or read only (the full list of operations is standard CRUD operations).

I ContentProvider again to assume that once the vehicle is interested in ContentProvider protection, it’s obvious that he wants the provider to be exported=true - otherwise you can make it exported=false and forget about the problem.

exported=true provider is needed in the password manager if you need to somehow "penetrate" the password database bypassing the program itself and retrieve data from there (well, for example, just the number of entries, cipher hashes, or something similar relatively harmless). ContentProvider on ContentProvider as a way to protect data is meaningless. Any data in Android can be obtained directly - it is enough to have superuser rights.

Now more to the point. Almost everything is written at the manifest level (well, except for the provider’s own code, of course), something like this:

 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ru.mypackage" android:sharedUserId="ru.mypackage.shared.user.id" android:sharedUserLabel="@string/myapp"> <permission android:name="ru.mypackage.MyProvider" android:protectionLevel="signature" /> <uses-permission android:name="ru.mypackage.MyProvider" /> <application <!--blah-blah--> > <provider android:name="ru.mypackage.MyProvider" android:authorities="ru.mypackage" android:exported="true" android:readPermission="ru.mypackage.MyProvider" /> </application> </manifest> 

Here, everything is more or less clear except for the item with android:sharedUserId="ru.mypackage.shared.user.id" is some alternative instead of making a garden with ContentProvider 'om - in fact, it is a declaration that access to application data is opened for applications with identical sharedUserId and matching signatures — by default, application data is in a private directory and closed for other applications. So if you need to access the data, you can sometimes do without the provider and stupidly open the data in this way.

For the rest, in essence, your custom provider is created, which is protected by your own signature. That is, access to the provider will only have an application that has permi ru.mypackage.MyProvider and has the same signature as your application.

Next, you need to keep in mind that the exported provider is essentially a separate process that runs at the time of installing the application or at the time of launching the system and lives without your application. Accordingly, let us assume such a moment that there is an appeal to the provider, but the application itself is not yet running. And as we remember, we are talking about a password manager, that is, the descrambler key is generated when the user logs on to the system. What we have? We have a call to the provider, but there is no key to decrypt the data. Well, if the provider does not need the key, and if you need it? If you need a key, you must run the application directly from the provider.

In general, the provider must know whether the application is running and if it is not running, either shut down or run the application through the Intent .

Whew like everything.

PS I would think that the ContentProvider in FIG is not needed in the password manager - there will be so much crap :) - it’s enough to do with sharedUserId

  • Allow me to ask, but under the phrase "и имеющее такую же подпись как и ваше приложение." Is the signature understood by the developer key or is it just the presence in the manifest of a similar string - android:sharedUserId="ru.mypackage.shared.user.id" ? - ermak0ff
  • 2 conditions must be sharedUserId : a) for sharedUserId be the same b) both applications must be signed with the same certificate here - Barmaley
  • aah, thanks, but then I thought that only option a) is required, then with security would obviously be a problem)) - ermak0ff
  • And how do you feel about the variant using intent and FLAG_GRANT_READ_URI_PERMISSION to access the application that has this access all the time? - pozharnik16
  • Comments are not intended for extended discussion; conversation moved to chat . - Barmaley

Found in the Chinese forum on the comp. Security - Drops (the page is still available in the Google cache).

  1. Install MinSdkVersion 9 or higher.
  2. Set the attribute exported=false if ContentProvider is not intended for use by other applications (it does not seem to be your case).
  3. Use parameterized database queries to avoid injection.
  4. If the provider will use your other applications for data exchange, set protectionLevel=“signature” to verify the signature.
  5. Make sure the data content doesn’t make (note: I do not understand, left without translation)
  6. Uri.decode() before calling ContentProvider.openFile() .
  7. Protect permissions when providing asset files. (comment: also not clear)

Encrypt the database, for example, using SQLCipher . If this is not done, an attacker who gains root access to the device can easily read the contents of the database. Example usage (in English) SQLCipher with ContentProvider .