create a permissions to restrict third party apps calling an activity android - android

I am having two android apps signed with same certificate. Also i am using the activity of one app in other android app by specifying a name in "intent-filter" tag. But because of "intent-filter" tag any third party app can call my activity.
Since both the apps are having the same certificates signed, can i restrict other apps calling my activity by providing some permisions? Any suggestions on this would be helpful to me.
-Ron...

First you could maybe remove the intent-filters if your activity is not meant to be used by other applications than yours ; why not use an explicit intent instead?
Thus your activity couldn't be created "by mistake" but only intentionally, ex :
Intent explicitIntent = new Intent(InvokingActivity.this, InvokedActivity.class);
startActivity(explicitIntent);
Then, to even prevent that from the outside, you could define your own custom permission and add it to your activity ; have a look at the android:protectionLevel attribute of a permission, whose value can be "signature".

Related

Android safety question using android exported

I'm not an android dev. I used capacitor to convert a web app into an android app. The new sdk 31 changes have required me to add android:exported=true onto the mainActivity tag in androidManifest.xml file since it has intent filters. Basically, in order for my app to be approved by google console I need to add this one property.
ELI5 - is this safe, what does this do ?
<activity
android:name="com.test.MainActivity"
android:exported="true" <---------------------------- this
android:launchMode="singleTask"
>
Yes, it's safe to use exported true is used correctly
The exported attribute is used to define if an activity, service, or receiver in your app is accessible and can be launched from an external application.
As a practical example, if you try to share a file you’ll see a set of applications available. Clicking on one of them will open the activity responsible to handle that file, which means that it’s declared on the Manifest with exported:true.
For more details https://cafonsomota.medium.com/android-12-dont-forget-to-set-android-exported-on-your-activities-services-and-receivers-3bee33f37beb

What's the function of `Intent.setPackage()`

What's the function of Intent.setPackage(String packageName), since the intent will find a match through the componentName set by Intent.setClassName(Context packageContext,String className) or Intent.setComponent(ComponentName component), you can find a match even you set a wrong packageName to the Intent.setPackage(String packageName).
setClassName() Targets an exact package name and exact component you want to run.
e.g. if you want to use the Gmail app to send an email using this to run the exact Activity(Component) you want to run.
setPackage() targets an exact application and offers you all components that can handle your intent.
If you don't fill these two it targets all apps and components which is not ideal in some cases e.g. you want to target only WhatApp to share content. If there is a case that you want to share that content on any social media app just ignore these two and stick with action, data, and ... fields.

Start activity in another app with restricting receiving app to have same signature

I have two apps A and B. At some point A calls startActivityForResult() with Intent that points to activity in B (using "action" attribute). Both apps will be downloaded from Google Play and will be signed with the same certificate.
Since some sensitive information will be exchanged in the Intent's data I want to prevent a bad actor from replacing app B and installing his own version with same package name and action attribute which will receive the control from app A when startActivityForResult() is called.
I know how to ensure that app B is called only from app A (custom permission) but I was wondering, is there a way to ensure that when app A class startActivityForResult() that only my app B will receive the Intent?
"installing his own version with same package name"
although playstore allows for apps to have duplicate names it enforces the uniqueness of any app package name. so this shouldnt happen.
moreover, you can use a custom action attribute name for starting B .
hope this is helpful for now .

Android - ContentProvider - custom permissions

I've a problem with content provider and custom permissions.
Let's suppose that App A have a content provider containing wonderful informations. These informations are a little bit intrusive, that's why it's better to have a permission to read them.
Let's suppose that App B is a 3rd party application and want to access to the content provider of A.
Let's suppose that the permission to read into the content provider is "com.custom.a.readpermission".
In A manifest, there is :
<permission android:name="com.custom.a.readpermission"/>
<provider android:name="com.a.provider.MyProvider"
android:exported="true"
android:authorities="com.a.provider.MyProvider"
android:readPermission="com.custom.a.readpermission"/>
In B manifest, there is :
<uses-permission android:name="com.custom.a.readpermission"/>
So, now, if I install A; after, I install B. B can access to the data.
But, if I install B before A, I get :
java.lang.SecurityException: Permission Denial: opening provider com.a.provider.MyProvider requires com.custom.a.readpermission
So, how to manage a custom permission in that case ?
So, how to manage a custom permission in that case ?
Your primary options are:
Use a built-in system permission, as opposed to a custom one. This is a good idea in general, if the nature of the sensitive data is similar to other data already defended by built-in permissions.
Catch this exception and tell the user that they need to uninstall A and B and install them in the proper order.
If A and B are both by the same author, use a protectionLevel signature permission and have the same <permission> element in both A and B. Then the installation order will not matter, and the user won't be bothered with any prompts to agree to this permission.
However, bear in mind that prior to Android 5.0, the fact that option #3 works means that any app installed before A could do the same thing as B does, except downgrading the protectionLevel from signature to normal. This is a known vulnerability. Android 5.0 requires that custom permissions are defined on a "first one in wins" basis, and the second and subsequent apps trying to define the same <permission> have to be signed by the same signing key as the app that actually did define it.
In truth, permissions are great for pre-installed apps and the OS itself, but defining custom permissions at the app level is... less than great.

Android: how to share code between projects signed with the same certificate

In Android documentation concerning code signing we can read: "By signing multiple applications with the same certificate and using signature-based permissions checks, your applications can share code and data in a secure manner."
How exactly such code sharing can be done? Is it possible to release main application and multiple exchangeable plugins then discover them at runtime? What does source code looks like and what are advantages over "standard" intents calls from/to different APK packages?
Use Context.createPackageContext() to instantiate a package for another .apk you are interested in. If it is signed with the same cert as yours, AND you are both using the same shared user ID, then you can use the flag to load its code into your process, allowing you to get the ClassLoader from the context and instantiate whatever classes you want.
Otherwise, if they are not signed the same and explicitly using the same shared used ID, you can only load its resources.
Please note that you can not change the shared user ID for an application (to something else or moving between having and not having a shared user ID) once that application is on market.
Say you want to call a public function of the dynamically loaded class. Use the following code snippet:
Context friendContext = this.createPackageContext("packageName", Context.CONTEXT_INCLUDE_CODE);
Class friendClass = friendContext.getClassLoader().loadClass("packageName.className");
Class noparams[] = {}; //say the function (functionName) required no inputs
friendClass.getMethod("functionName", noparams).invoke(friendClass.newInstance(), null);

Categories

Resources