I downloaded an APK from a 3rd party source (not Google Play). My question is that can this android app, although stated that it can only access my USB storage, could it also do other things (such as read IMEI) without stating it explicitly? In essence what I am wondering is that does the Android System actually prevent it or is it just something the developer states in their manifest?
As Meer Borg correctly states in his answer: when an app is installed, the package manager reads its
Manifest, and notes the permissions requested into files the Android system controls (
/system/etc/permissions/*.xml (one file per app)). Additionally, for each permission there is a specific user group, which will be assigned to the app1. So each time the app tries to access a feature requiring a permission, this is checked against: if the permission was declared in the
Manifest, access is granted – otherwise it's refused. note that this is a simplified description, though
While this is the general rule, for some things there are possibilities to work-around the permissions. If an app e.g. wants to send something to the internet, it could also do so calling an "intent", asking the browser to open a certain page (like e.g.
http://bad.server/collector.php?info1=some_info&info2=more_info). However, this would not go un-noticed by the user, as the browser would open in foreground and show this action. So if an app would make use of this feature, the outcry would be heard (usually).
If a dev really wants to do "bad things", he could also use another way: have one app with all the required permissions, and a second with almost none. If the user has both apps installed, the second one could call the first (big-permission) app to process "things" it cannot do itself (due to lacking permissions) – in the same manner as described above for accessing the internet. note that this priciple is used e.g. for addons, and "inter-app-communication" in a positive sense, too
An app is restricted to the permissions it requests, and cannot directly access other "things". "Indirect" access would not go unnoticed.
This is just an abstract, and simplified presentation. I'm not in Android development, so some dev might have better understanding and correct me, or add to the above.
1 Example (note the "groups" list):
shell@android:/ $ id uid=2000(shell) gid=2000(shell) groups=1003(graphics),1004(input),1007(log),1009(mount),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats)
id command (without parameters) shows information about the "current user". In this case, I was using
adb shell, so the user is the "shell app" (rather the integrated Unix shell). The list of groups shows which permissions are granted to the shell, So it can e.g. read and write the SDCard, access Bluetooth, and the Internet (plus some more things).
Each application you install has a file called manifest.xml in it that dictates what the app is allowed to access. When you install an app it checks that file and shows you what permissions are needed to install that Application.
So unless your phone is rooted, and uses an exploit. Or you repackage that file and its manifest file to add more permissions...it will only access the USB storage as quoted. The Android System prevents any other access and the code that tries to access those other permissions will simple return an error from the program point of view.
But I believe that even accessing USB storage is an issue because it can access all of the other files other programs create using USB Storage, not the entire file system, just a sub part of it that is defines as "USB Storage". But as the app doesn't access the internet, whatever the app accesses stays on your device.