I have main application A that uses other apps as plugins, lets say B, C and D. I have no control over what app will be installed first.
How do I define signature level permission so only main app A can start plugin apps B, C and D?
Plugins don't have UI so user can't start them manually but I need to make sure only my main app can launch them. I tried defining the permission in plugins like so:
<permission
android:name="my.custom.permission.START_PLUGIN"
android:protectionLevel="signature"/>
And then in my main app:
<uses-permission android:name="my.custom.permission.START_PLUGIN" />
This doesn't seem to be correct approach. Can anyone tell me the correct way to achieve what I described above? Thanks.
EDIT: My plugins are implemented as bound services with AIDL interface.
To answer my original question, to make my example work, all you have to do is add permission attribute to your application components you want to protect. This is done in Manifest.xml file.
Let's say you have activity called MyActivity that you want only your apps with START_PLUGIN permission to be able to launch. So in your plugin, you do:
<permission
android:name="my.custom.permission.START_PLUGIN"
android:protectionLevel="signature"/>
and:
<activity
android:name=".MyActivity"
android:permission="my.custom.permission.START_PLUGIN"/>
The last one will ensure that only apps with START_PLUGIN permission can access that activity. So all you need to do is in app that should start this plugin use the permission like so:
<uses-permission android:name="my.custom.permission.START_PLUGIN" />
To decide if you want to use permission with signature level protection, or sharedUserId as suggested by #pskink in comments, consider following:
sharedUserId tightly couples both (or more) apps, enables them to access not only specific activities but their files (even SharedPreferences) and views and basically removes any level of separation
custom permission enables to to specify which parts of your app are to be protected, leaving you with more control but also with the need for IPC like AIDL
Links:
sharedUserId Android Reference
How to access data of app with sharedUserId
AIDL Reference
Android permission protection levels
Related
Does the Android Manifest check for the available components to be used before an application starts running, or does the system check for the Android Manifest every time a new component is being instantiated? By components I mean activities, services, etc...
What is the process involved?
Also, can an application still go back and forth to check on the android manifest even after it is running to check on xml activity attributes such as the android:name, android:label, or even intent filters, for different purposes such as to see whether a component to be used has already been defined?
Well to say it in a simple way-
Manifest contains permission like- "SD card read/write permission". So, while installing an app if you don't have a SD card than your won't get installed.
Again manifest contains "minimum SDK version"- which checks what OS version you have in your mobile, if your mobile OS version is less than the minimum version defined in manifest than the app won't install in your mobile.
In the manifest you have a list of all the activities and services too. So, without adding these in the manifest- your activities/services wont work.
So, these sort of checking and permissions are in manifest - the information the system must have before it can run any of the app's code.
Hope i have been able to keep it short and simple :-D
The manifest is a part of the app - it gets packaged with the app in its installation APK.
The manifest tells the system what APIs the application will use. When the app is installed, the system tells the user what sets of potentially sensitive APIs the application will use (as listed int he manifest) and if the user allows the app to be installed the system then assumes that the use of those APIs is permitted.
The OS will not permit the app to use other sensitive APIs that the app did not declare in the manifest.
Android Manifest file contains important information like the Java package name of the application, permissions, descriptions about activities,services... The system must have these information before running the app code.By this reason, the system doesn´t check the Android Manifest in runtime.
More here:
Android Manifest - Android Developer
How Do we find what level of Android protection is required for a specific permission.
Lets say we have android.permission.SET_ACTIVITY_WATCHER(docs)
What protection level does it fall into?(docs)
Regular
Dangerous
System or Signed
Signed
You can find some permission with there levels here:
https://github.com/android/platform_frameworks_base/blob/master/core/res/AndroidManifest.xml
and an other solution is the following code sample:
getPackageManager().getPermissionInfo(name, 0).protectionLevel
in you're case is this the infos:
<!-- Allows an application to watch and control how activities are
started globally in the system. Only for is in debugging
(usually the monkey command).
<p>Not for use by third-party applications. -->
<permission android:name="android.permission.SET_ACTIVITY_WATCHER"
android:label="#string/permlab_runSetActivityWatcher"
android:description="#string/permdesc_runSetActivityWatcher"
android:protectionLevel="signature" />
Usually Creators of respective API sets the permission depending who are the recipients of this API.
Best way is to grep the source code for the respective API permission.
Android document fairly states what is intended for 3rd party and what not. Permission is usually "Normal" for all things intended for Normal.
http://developer.android.com/reference/android/Manifest.permission.html#SET_ACTIVITY_WATCHER
To answer your permission question
https://android.googlesource.com/platform/frameworks/base/+/master/core/res/AndroidManifest.xml
Look at fragment .. it is signature permission.
Allows an application to watch and control how activities are
started globally in the system. Only for is in debugging
(usually the monkey command).
Not for use by third-party applications
permission android:name="android.permission.SET_ACTIVITY_WATCHER"
android:label="#string/permlab_runSetActivityWatcher"
android:description="#string/permdesc_runSetActivityWatcher"
android:protectionLevel="signature"
I have an applications which has different activities. One of those activities can be called from other applications.
Is there a way to set permission that this certain activity can be called only from specified applications (e.g. com.other.application and com.different.application). I would configure those allowed applications in AndroidManifest.xml or somewhere else.
Thanks
You can define your own permission and only allow apps that request that permission access the functionality.
Define Permission
<permission android:name="uk.co.packagename.mypermission"/>
Set permission on activity
<activity android:permission="uk.co.packagename.mypermission" android:name=".ActivityName"/>
Use Permission
<uses-permission android:name="uk.co.packagename.mypermission"/>
You can either declare your activity to be accessible or not by outside of the application package, but for some application accessible or for some not is not feasible.
To make private an activity to your application you need to set property of Activity in manifest: exported=false;
My application needs that GPS is active at startup as for it to proceed.
Iam testing the app, so I'm mocking the GPS by adding <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" /> to my AndroidManisfest.xml file.
This works ok. But I want to keep things separate. Is it possible to add a permission at runtime when we are testing?
EDIT:
I know from the docs that:
Android has no mechanism for granting permissions dynamically (at run-time) because it complicates the user experience to the detriment of security.
But as a matter of testing the application, is there an alternative?
Thanks
There is no way to add Android permissions at run-time. They must be specified in your manifest.
If you have a separate test application, I believe you only need to put this permission on your test application.
EDIT A test application is really no different to Android than a regular one in terms of permissions. I would just put the permission in your test application's manifest and not worry about it.
I want to define a permission in my Android app, and let other third-party apps to use. This permission is used to restrict calling of my modules. That is, third-party apps must request the right permission to call my module, just like using system permissions defined by Android system, android.permission.INTERNET or so.
In my test, I defined the permission in my app, say "my.apps.permission.my_permission", and then install it on emulator. In some of my Activities, android:permission="my.apps.permission.my_permission" property is added. This property forces the apps calling my activities must have the right permission "my.apps.permission.my_permission". Then in a test app, request the permission in AndroidManifest.xml, <uses-permission android:name="my.apps.permission.my_permission" />
The problem is, in the test app, which will call my permission-required activities, when I call startActivity(), I got a SecurityException : Permission Denied. But, if I defined a permission with the same name in the test app, everything works fine.
And, the followings are my conclusions:
1) It seems that, the permission defined in my app, "my.apps.permission.my_permission", is not visible to other third-party apps. How to make it visible, so that other apps can use my permission just like the ones defined in Android system?
2) Even is visible, Android won't check user-defined permissions with name conflicting.(I test this by define a permission with name "android.permission.INTERNET" in test app and overrides the system-defined one, and require "android.permission.INTERNET" in my app, and still, everything works fine.) If so, every other apps can define a permission with the same name that my module requires, and cheat my app. Is that right?
Anyone can help?
Thanks a lot!
I got the answer.
My own app, which defined the permission for other apps to use, must be installed before other apps who want to use my permissions. Otherwise, those apps must be re-installed, to use my permissions. No other operations or codes are needed, just <uses-permission android:name="my.apps.permission.my_permission" />, the same as other system defined permissions.
And, several apps may define permissions with the same name, conflicting with each other. The first installed app occupies the conflicting permission name, others won't overwrite or change the original permission.