Monday, April 25, 2011 - 18:34

Android permissions revisited. It still sucks.

The usual answer you hear when you raise the topic of permissions with Android is "Works as intended" and all I can say about that one is: If that was your intention you might reconsider visiting the drawing board because your intention sucks big time.Android's security model is rather effective, simple and potentially easy to understand. Since post installation tampering is not (easily) possible There's not really much space for error. It still sucks because it's an all or nothing model. It's not even that you're supposed to use an app the way the developer intended to. I quite often do not need "unrestricted internet access". All I might need could very well be access to the user's Google account. And that's quite a difference from accessing the user's Google account and accessing warez.ru, pr0n.com and hax0rs.cn. The user either needs to trust me or needs to trust Google's audit process, which wasn't exactly great lately.

How to fix it without compromising it. You don't need to actually change the permission in the app. The manifest can be the very same as it is. We just need a layer on top of that. One the user can change. Basically the same functionality we already have with some root-requiring firewall enhancements. They are rather effective but they have two problems.

  1. They only limit internet access and not access to other parts of the system. I.e. the address book
  2. The app in question is not aware of this situation and will just fail.

A control layer on top of the in-app manifest based security model that is only capable of restricting an application could snap into the chain and provide information to the application about its status. I.e. you don't have unlimitted access but you can access google.com.

In an abstract way it could be handled like this from the application's POV.

let's say you want to access something on the net. The required permission would be android.permission.INTERNET.

A very simple test prior to execution of code could clarify whether the app is limited or not.

try{

if ( x( android.permission.INTERNET, "google.com" ) ) { you're good to go; }

} catch ( AuthorizationException  e ) { does_not_compute }

or this one

try{

if ( x( android.permission.CALL_PHONE ) ) { you're good to go again; }

} catch ( AuthorizationException e ) { no calls for you baby }

Something similar is already required anyway with location based services. You can access the GPS receiver. But you cannot turn it on. If you need it you kindly have to ask the user to switch it on. This was possible in eary versions of Android. I think 1.0 and 1.1. Google removed it for a good reason. That very same reason however is valid for quite a few permissions.

I don't see any way this layer could void the manifest based security model as it's only possible to limit permissions. A possible escalation exploit would still hit the hard limits of the underlying model.

At the very same time the user gets a real choice what to allow and what not. And as a bonus on top. You don't have to use it.

This debate is up - and sometimes rather heated - for quite some time now and I fail to see a valid reason not to implement it. Works as designed is not a valid excuse if the design is fundamentally flawed. It's too complicated? Oh come on. If Apple bothers their users with this it can't be that hard.

The only downside it has is more work for coders. But I'd happily do that work because it relieves me of debates why an app needs a particular permission. If you don't want it. Lock or limit it. If you boast it the app might not work anymore but that's your choice, not mine.