Where are Android Instant Apps permissions checked within the framework? - android

Other questions on this topic have been asked here:
Classes for Permission Checks Android
how are android security permissions checked at run-time?
How does Android enforce permissions?
But none of them answer what I am trying to figure out. I want to know where exactly I can find the functions or methods that literally check the permissions I'm requesting to see if I'm allowed to have that permission. More specifically, I want to find out what happens with Android Instant Apps permissions, since IA allows only a fraction of all Android permissions (the list can be found here https://developer.android.com/topic/google-play-instant/faqs).
For them there has to be a check somewhere, a whitelisting method that takes the permissions I'm requesting, understands that my application is an Instant App (rather than a normal one) and so it knows to check what I requested against that limited list only. That way it ensures I cannot ask permissions that are not even supposed to be allowed.
I want to understand and see where this happens, source code of these checks, especially for Instant Apps. I have started from the checkSelfPermissions() function used when implementing the Android Runtime Permissions. Through the function call trace feature in Android Studio and the xref (http://androidxref.com)
I went back as much as possible until I found the Context.java file (http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/content/Context.java) which has the prototype declarations with comments for each function.
public abstract int checkPermission(#NonNull String permission, int pid, int uid);
I just don't know where to find the definitions with the actual function body and code for it though. Context.java doesn't have them. And I think I am going more and more down a rabbit hole and a bit too low-level with these:
http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/content/pm/PackageManager.java#532
http://androidxref.com/8.1.0_r33/xref/frameworks/native/libs/binder/IPermissionController.cpp#39
http://androidxref.com/8.1.0_r33/xref/frameworks/native/libs/binder/IPermissionController.cpp#39
especially the last two, which not only do I not know if I'm on the right path with them, but I'm trying to figure out that remote()->transact function now and where it's defined, but we're in android native c++ territory now...
Any help or pointers would be immensely appreciated, it shouldn't be that hard to just go through the AOSP source code, right?

For future reference, in the end I have managed to solve it. It took way longer than I thought, but as it happens with most things, the answer was a lot simplier than thought.Turns out that yes, I was definitely going down lots of rabbit holes, but only up to a point. This whole process of search was actually useful in realizing where the answer would lie.
So the first step was successfully finding the actual proper, "low-level" implementations of the permission check or the permission granting action, and the functions are grantRuntimePermission and checkUidPermission, both in the PackageManagerService.java class. Here are the interesting bits, of each function:
http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java#5655
http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java#5335
That is where the checks are being performed, but the system somehow already "knows" about the permission and that it is runtime or not, instant or not. The crucial bit (which also kinda hinted to me what eventually I found the answer to be) is to look at the BasePermission objects created.
I found that the Android OS treats permissions in a more modular way, where each permission, rather than left as a simple string to do a check against, gets transformed into an independent BasePermission object. This gives it a more defined importance, as these objects now contain, besides the permission name, attributes such as the sourcePackage name, permission type, UID that owns the permission, and most importantly, the protectionLevel, amongst others. Here is the BasePermission.java class:
http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/pm/BasePermission.java#23
It seemed that the BasePermission objects get created within each application, based on that application. So in the context of an instant app, the Android OS attributes the permissionLevel to each individual permission object accordingly as it learns the application is, in this case, Instant. Here is the important bit of code:
if (isUidInstantApp) {
BasePermission bp = mSettings.mPermissions.get(permName);
if (bp != null && bp.isInstant()) {
return PackageManager.PERMISSION_GRANTED;
}
} else {
return PackageManager.PERMISSION_GRANTED;
}
So it's possible to see how it creates the BasePermission object, based on permName, from a list/array of pre-created permission objects (mSettings.mPermissions) that the System somehow builds for the current application only. This only answers the "where is the permission check made?" question, but now the problem is "how does the system know how to create the BasePermission objects and assign to each of them the correct protectionLevel?". Initially I was completely unable to find where the "mPermissions" list gets populated. Then it hit me: I didn't actually need to know that.
All Android permissions and their names are defined in the global AndroidManifest.xml file. Whenever you use permissions in your application code, you call the Manifest.permission.PERMISSION_NAME string, right? I thought that the manifest would only contains the names of each permission, declared as a string. What I didn't expect was that the only other tiny piece of information the manifest declares is (you guessed it)... a per-permission protectionLevel value. For each permission it would state if it is a "normal" permission as opposed to the "dangerous" ones, as well as if it can be used for instant apps or not. And as expected, only the 10 (at the time of this writing) defined permissions for instant apps from the official docs had the "instant" attribute beside the other available protection levels. Here's one of them:
http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/res/AndroidManifest.xml#773
That is how the system knows to build the BasePermission objects, wherever it does that. And there was the whitelisting that I was looking for.
Even if I did look at the manifest as first step in my research, I probably wouldn't have known that the answer was right there in front of me. The knowledge of BasePermission objects was crucial to understand how the permission model and checks are implemented.
Next step now would be to actually find where exactly the system creates the base permission object based on these protection level strings in the manifest. I am guessing there should be an association of those strings to a binary integer such as "normal" or "normal|instant", number which is then used by the BasePermission class to construct the objects' protection level and ultimately define if they're instant.

Related

Trouble Conceptualizing Android File System Access

I want my app to automatically load data from a file at startup & then display a summary of this data for the user. I thought this would be simple, but...
I almost had it working, but found out that it would be tricky putting the data file on the emulated Android provided by Android Studio. So I put a basic version of the file in the package as an asset. My code checked for the file, and if not found, copies the file from assets to the phone storage. So far so good, but then I realized that this didn't really meet the requirements, because the user couldn't customize the file (through another app or by putting a new version of the file on her phone).
I found I needed to use "external" storage (which isn't really external, it's merely shared / public storage). So I used getExternalStoragePublicDirectory() to get access to the Documents folder. In the part of my code which copies the asset file to the Documents folder, I get "java.io.IOException: No such file or directory" when I try to create the target file.
This really threw me for a while, since I had preceded it with mkdirs() to ensure the folder(s) existed and I was trying to create the file in the first place.
After lots of poking around on S/O, it seems my problem may be that I don't have permissions to read / write in the Documents folder. So this is where I can't get my head around how this is supposed to work.
In my Activity's OnCreate(), I want to load the data from my file. But I need to check the permissions first. This is guaranteed to fail the first time, because the user has never granted my app this permission before.
So then I need to request the permission. But this means I can no longer load my data in the OnCreate() method, as I will get the response from the user asynchronously, in a callback method (onRequestPermissionsResult).
If the user says 'No' to my request, I need to make sure the app quits gracefully. If she says 'Yes', then... what? At this point I'm in a callback and my OnCreate() method is no longer running. How can I get back to setting up my Activity?
If I load the data file in the callback method, that only works for the initial case where the user must give permission. But after that, my app (most likely) will not lose permission, so my app will not need to ask for it. The callback will never be executed in this case. So my data file must be loaded... where?
But all of this only happens if the user is running Android 6.0 or higher. If it's an earlier version of Android, then my app can load the data in my Activity's OnCreate() method.
Oh... my head hurts!
How is all of this supposed to work? I don't need a link to the relevant methods. I need a conceptual model - a diagram would really help!
Here's the solution in a diagram: Permissions Conceptual Diagram
How can I get back to setting up my Activity?
Move the "setting up my Activity" code that depends on file I/O to a separate method. In onCreate(), check to see if you have the permission, and if you do, call that method to set up your activity. If not, call requestPermissions(). In onRequestPermissionsResult(), if you now have the permission, call that method to set up your activity.
See this sample app, which performs disk I/O from external storage using runtime permissions. The permission-handling logic is isolated in an AbstractPermissionsActivity, leaving the main activity class to handle the real business logic.
If it's an earlier version of Android, then my app can load the data in my Activity's OnCreate() method.
Well, you should be doing this disk I/O on a background thread. You can kick off that I/O from onCreate().
If you are using ContextCompat and ActivityCompat for checking and requesting permissions, respectively, your code will "do the right thing" on older devices, as those classes do the version checks for you.

How to identify a malicious android app

I am developing android an app to detect malicious apps .we are planning to detect malicious apps based on the requested permission.....does permission alone will help us to detect malicious apps or do we need to consider characteristics like use of dynamic code, usage of static http url....any help appreciated. ...
I will breakdonw this question is several smallwer parts:
detect malicious apps
This is perhaps the harderst part in what you desire to do. Most anti virus, anti malware, etc. will usually search a "footprint" in the source code of the binary that is generating the instructions. If you found a number above threshold of footprints, you can guess that file is malware.
we are planning to detect malicious apps based on the requested permission
I am going to say explicitly: no...
As far as I have seem, most "weird" requests, are usually due to the programmers not fully understanding what the permission grants, or even why/what is necessary for.
This is so much an endemic problem, that Google itself changed how permissions work (if I am not mistaken, from K to L, or L to M or something in those updates)
Then again, an alarm app, that wants network access, wants to read all files in the system, wants to read/writte anything anywhere, wants to use your gps, etc etc, then that looks like malware on itself (and usually no READING user would use it).
do we need to consider characteristics like use of dynamic code
Yes. While Java itself cannot interpret its code "on-the-fly", DEX allows us to. And the most common hijacks are usually apps that do nothing, but then create an entry point to render javascript content, and perform some unexpected code.
usage of static http url
That is on itself not that much of a risk, since most browsers will request some security credential, and at least warn the user that he is on un-trusted network. A secondary problem that usually arrives is geerating the URL "on-the-fly" then asking an empty request to alter its request to that.
If an app is then requesting any web-based content bypassing the system (not a security issue, sometimes the programmer is simply making "less effort than necessary to fullfill a client request", then looking at static addresses, or even IPs is usually of no significant security value.

how to get Responsible API calls for used Permissions?

Consider
PackageInfo info1 = pm.getPackageArchiveInfo(apkPath,PackageManager.GET_PERMISSIONS);
In this statement, by using GET_PERMISSIONS I can get the set of all permissions used in the application.
In the same way can i get the API calls?
Thank you. I am new to this android programming if it is a simple question please forgive
No, you cannot get the API calls by any easy method, and arguably not even by a hard method.
If you had access to the application's installed .apk (and at least on older Android versions you did), you could read through it for obvious invocations of platform functions. (This is a form of "Static Analysis")
However, Java (and hence Dalvik) supports a mechanism called "reflection" which allows looking up and calling functions by name - a name that could be constructed at runtime by circuitous means, or user or network input.
Much of the actual functionality used for calling functionality in the system process is also ultimately performed by name, making another place where functionality not present in the static file could be added at runtime.
Finally, the native underlayers of Android (and likely the DVM as well) permit a determined programmer to dynamically designate arbitrary "data" to be "code" and then execute it.

extras Bundle in Android Notification usage?

Although not documented in the Notification Documentation, looking at the Notification.java for Jelly Bean there is an extras Bundle with an EXTRA_PEOPLE key defined.
The type is listed as TBD, can anyone from Android provide direction as to what this may look like? Do you expect this to be a list of String names, or maybe Long rawContactIds? Will there be any recommended ordering (such as meeting organizer versus attendees, or a Gmail From versus CC)?
Are there any changes in Android 4.2 that will utilize this, or is this still truly TBD?
Even if it is filled out now, relying on it is risky- if it's labeled TBD then they can change it in any minor release without telling you, any code depending on it is likely to break. I wouldn't risk it for anything I was releasing.
If you want to test it out though, write an app that uses it and use java reflection to get the class name of the object and print out the values. If its a collection class, repeat on whatever object it holds and let us know.
Still truly TBD.
(General rule: Avoid using anything that's marked #hide unless you really know what you're doing.)

Android Application Level Scope Variables

I understand that there is no Application Level Scope available to be able to define shared logic/data, and that each activity is essentially a stand alone application tied together by the manifest...
BUT I have a group of user access permissions that I am getting via a web service call and do not want to make this call in every activities onCreate().
I am using SharedPreferences in the application, but since the permissions are not intended to be editable by the user, the flat file exposure on android devices feels like an insecure way to handle this.
I do need to re-request this info if the application is restarted, so I believe the least expensive would be to store it in a variable.
I am aware of IntentExtras but we are talking about a Settings "Object", not a primitive type.
right way to handle this situation?
You can actually create an "Application" class that can be used to essentially create Application wide settings.
Just create a new class and extend Application, then set any class members and appropriate getter/setter methods and you can access them throughout your application.
You then need to update your manifest as follows:
<application android:icon="#drawable/logo"
android:label="#string/app_name"
android:name=".application.CustomApplication">
Then in any activity you can access it as follows:
CustomApplication app = ((CustomApplication)getApplication());
I think that using shared preferences is fairly secure. Only advanced users with root, custom roms and hacking knowledge would be able to take a chance at it! (I'm not even sure that this would be possible).
Besides SharedPreferences, you could also implement a custom Application object and keep your permissions there.
Anyway, as a developer I think that it's much more likely to be hacked somewhere within the request I do to get the user permissions (use https, etc) and my application being decompiled.

Categories

Resources