David Wasser
David Wasser

Reputation: 95578

Nasty issue with custom permission dependencies

I have an app (let's call it "L"), that provides a Service that other apps can bind to. The Service requires that the binding client have the permission "my.permission".

I have another app (let's call it "X"), that uses the Service in "L". In the manifest for "X", I have:

<uses-permission android:name="my.permission"/>

Now I have the following different scenarios on Android 4.4 (Kitkat):

  1. User installs first app "L" and then app "X". User runs app "X". "X" successfully binds to the Service in "L". Customer is happy.
  2. User installs first app "X" and then app "L". User runs app "X". "X" fails to bind to the Service in "L" due to a security exception. Android claims that app "X" does not have the required permission "my.permission". Customer is furious.

After lots of experimentation, it turns out that in the second scenario, when the user installs app "X", Android sees the permission request in the manifest, but doesn't know anything about permission "my.permission", so it refuses to grant app "X" this permission. The only way to fix this is to uninstall app "X" and install it again. At this time, since app "L" is already installed, Android knows about the permission and grants the permission to app "X".

After more experimentation, I came up with a solution to the problem. I added the following to the manifest for app "X":

<permission android:name="my.permission/>

Now, when I install first app "X", Android knows about the permission (since it is declared in the manifest) and grants the permission to the app. Customer is happy.


some time later...

Now I have the following scenarios on Android 5.0 (Lollipop):

  1. User installs first app "L" and then app "X". Android refuses to install app "X" due to INSTALL_FAILED_DUPLICATE_PERMISSION. Customer is furious!
  2. User installs first app "X" and then app "L". Android refuses to install app "L" due to INSTALL_FAILED_DUPLICATE_PERMISSION. Customer is furious!

To remedy this problem I now remove the <permission> declaration from app "X" and try the install scenarious again on Android 5.0. I now have exactly the same problem as on 4.4.

The only way I have found to get this to work is to force the user to install app "L" before app "X". Customer is not happy.

Any ideas?

Upvotes: 0

Views: 229

Answers (1)

CommonsWare
CommonsWare

Reputation: 1006914

Now, when I install first app "X", Android knows about the permission (since it is declared in the manifest) and grants the permission to the app. Customer is happy.

Unfortunately, this is also a significant security flaw, as any app can do the same thing. Custom permissions are designed primarily for firmware/pre-installed apps.

Any ideas?

The big one is to sign both L and X with the same signing key. In that case, they can have the same <permission> element. However, I am assuming that they are not being signed by the same key, otherwise you would not have posted this question.

The only other alternative that I know of is to not secure via custom permissions, but use other security measures instead. In L's onBind(), you should be able to use getCallingUid() to see who the caller is. Validate, via package name and signature check, that X is the caller. If there may be more than one app filling the role of X, you will wind up with a whitelist in L of package name/signature hash pairs to check.

Upvotes: 1

Related Questions