I have 2 applications A and B.
I want to start an activity in B from A. So I am using an implicit intent. Is there any way to make sure that only the activity in B is invoked by the intent?
i.e In the event that a hacker puts his application on the device trying to receive the same intent, I want to prevent that.
Use the setPackage method to specify whicj app should handle the intent. Here is an example using ZXing:
final String ZXING = "com.google.zxing.client.android";
Intent intent = new Intent(ZXING + ".SCAN");
intent.setPackage(ZXING);
as documention says about android:exported=false:
android:exported
Whether or not the activity can be launched by components of other applications — "true" if it can be, and "false" if not. If "false", the activity can be launched only by components of the same application or applications with the same user ID.
The default value depends on whether the activity contains intent filters. The absence of any filters means that the activity can be invoked only by specifying its exact class name. This implies that the activity is intended only for application-internal use (since others would not know the class name). So in this case, the default value is "false". On the other hand, the presence of at least one filter implies that the activity is intended for external use, so the default value is "true".
This attribute is not the only way to limit an activity's exposure to other applications. You can also use a permission to limit the external entities that can invoke the activity (see the permission attribute).
so ,use android:exported=false in Activity B and use IntentSender in Activty for getting infromation of Intent means from which component want to start your Activty B
If you are using explicit intent, activity specified in intent would be invoked only.
You can add Data, Action, Categories, to limit filtering of component to target only your activity, in case of implicit intent.
You could encrypt any data sent in the intent using a simple Public/Private key encryption. A common approach is to use PGP encryption and Im sure there is a library that is compatible with Android out there.
This would make sure that any hacker would not be able to steal the data sent via intents, as long as they don't have the private key.
That being said, it may be tricky to handle the private key as a good hacker may be able to de-obfuscate/de-compile your application and grab your key. Therefore you may need to keep said key on a central server.
Related
Can App A start a component in App B through explicit intent?
I understand that general use of an explicit intent is to start a component within the same app. Implicit intents are used to cross process boundary.
Scenario:
App B defines and uses a custom permission "foo"
App A uses
PackageManager API to identify App B (app which defined "foo")
Can App A start a component within App B through explicit intent?
I don't think this is possible because explicit intent needs- app package and component name.
if (PackageManager.PERMISSION_GRANTED == packageManager
.checkPermission("foo",
pk.packageName))
results.add("package name: "+pk.applicationInfo.packageName+ " class name:
"+pk.applicationInfo.classNa);
}
Class name is null. So, per my understanding there is no way inter-app communication is possible through explicit intent just by relying on PackageManager APIs. In Android 5, you can call AIDL Services only through explicit intent but at dev-time the caller needs to know package and component name of app exposing the AIDL. Is my understanding correct?
Can App A start a component within App B?
App A can try. Whether App A will succeed depends on several things, including whether the component is exported and whether the component is secured by a permission.
I don't think this is possible because explicit intent needs- app package and component name.
The application ID and component name are both strings. Apps can use strings. Correctly getting the application ID and component name may take some work, depending upon the relationship between App A and App B.
As a counter-example, the only way to bind to a service on Android 5.0+ is via an explicit Intent. Hence, if App A wishes to bind to a service exported by App B, App A has no choice but to create an explicit Intent.
No way. If you want to start something that's outside your app you have to declare a implicit intent. Otherwise android will look for it inside your package, probably not gonna find anything and crash.
From the docs:
You'll typically use an explicit intent to start a component in your
own app, because you know the class name of the activity or service
you want to start.
Under "Intent Types" - http://developer.android.com/guide/components/intents-filters.html
So, typically you will not... but you can do this however it is not straightforward. To create a proper explicit intent, you will need the application context and the class.
To get the context of another application:
createPackageContext (String packageName, int flags)
http://developer.android.com/reference/android/content/Context.html#createPackageContext(java.lang.String,%20int)
For the class, you can request 'Activity' and 'Service' classes from package manager. You could also try to use reflection. You can also use the fully qualified string name of the package and assume it is correct and/or will not change. If you want, you can include a stub of the class in your app, thereby obtaining a reference to it (if you have access to the source or a stub library).
If there are permission restrictions, you will need to request permission.
I know that public (named) intents that are registered with the system and can be called from any application and private (anonymous) intents that are used within a single
application. please can anyone give me an example for better understanding.
Thanks in advance
Sorry no time to write a full answer, but you can create custom permissions in order to sign your Intents & BroadcastReceivers.
When you use these custom permissions, only apps that have been signed with the same signing key, and include that custom permission, can see these Intents.
This question might help you:
How to use custom permissions in Android?
#Commonsware explains the issue really well in a recent blog post:
Don't have an Accidental API - The CommonsBlog
The Android documentation does probably the best job of explaining it, here is a relevant snippet:
There are two primary forms of intents you will use.
Explicit Intents have specified a component (via
setComponent(ComponentName) or setClass(Context, Class)), which
provides the exact class to be run. Often these will not include any
other information, simply being a way for an application to launch
various internal activities it has as the user interacts with the
application.
Implicit Intents have not specified a component; instead,
they must include enough information for the system to determine which
of the available components is best to run for that intent. When using
implicit intents, given such an arbitrary intent we need to know what
to do with it.
This is handled by the process of Intent resolution,
which maps an Intent to an Activity, BroadcastReceiver, or Service (or
sometimes two or more activities/receivers) that can handle it.
Explicit intents you use in your activity to start internal activities.
While implicit intents are used often used to launch other activities like when you want to share a link or email something, you send out an implicit intent and let the user decide the email client to use to send the email or to share the link.
There are some instances where you might want to use an implicit intent to run an internal component of your app, because it seems to be more stable.
background:
i've noticed that for regular activities within, it is possible for any application to open the activities of my app .
question:
is it possible to allow only my own app (or apps , or package) to send and receive intents inside the same scope , so that other application won't be able to receive them or interfere with the flow of the app?
example:
suppose i have a broadcastReceiver that listens to some kind of intent , but this intent is only meant to be used by another service/activity that resides either inside my app , or inside another app that i've created , but i don't want others to be able to use this intent.
please help me.
setPackage()
Set an explicit application package name that limits the components this Intent will resolve to. If left to the default value of null, all components in all applications will considered. If non-null, the Intent can only match the components in the given application package.
or you can use setSelector() , but not both.
suppose i have a broadcastReceiver that listens to some kind of intent , but this intent is only meant to be used by another service/activity that resides either inside my app , or inside another app that i've created , but i don't want others to be able to use this intent.
In addition to Reno's fine answer, for your specific requirement quoted above, use LocalBroadcastManager. Not only do you get the security you seek, but it is more efficient. LocalBroadcastManager is available in the Android Support package and AFAIK should work going back to Android 1.6. Here is a sample project using LocalBroadcastManager.
I am working on the security aspects of my android application.
I would like to know about the ways to secure the Intent data and extras while sending it from one application to another so that no other application other than these two can snoop it.
One of the brute-force approaches would be to use android's encryption-decryption to encode intent data, is there a better way to achieve the same ??
Thanks in advance.
As pointed in the other answers, although you can send an intent to a fully qualified activity, nothing prevents someone from creating an application with the same package.
You might want to add an additional security step to this scheme:
First send a 'Challenge' intent to the remote activity (it should, for example, encrypt a random string you provided using a shared passphrase and send it back to you).
If that first security step is ok, you may freely send unencrypted messages to this remote app by using its fully qualified activity.
This is rather lame security, but perhaps it's sufficient for your needs.
Please take a look at CommonsWare's comment below.
A more secure way might be to code your activity as a Bound Service, keeping the Challenge step, but by means of more private communication.
My guess is that if you use an explicit intent, i.e. specifying the class to which the intent is to be sent to, then no other class can intercept that intent and look at its data.
This method however, may fail if the class name in the application that you're trying to send the information to changes.
If an intent specifies the the target, which is part of the sender application's package, then other applications won't have the chance to capture it - it will be delivered to the intended receiver.
On the other hand, if you send an intent to another application, there is no guarantee that the receiver of the intent will have the implementation you expect: if you send your intent to com.mycompany.security.SecureReceiver, but instead of your application, another application is installed with the given class description, than you will send your intent to that application.
Also, Android is an open system. If someone compiles his own application framework, than he can manipulate the Intent delivery system.
Do you want to protect your data from the user, or from malicious applications?
I have written an Android Application and the generated .APK file I uploaded in Android Market. So, a User can download that apk and install in his device.How can I restrict my apk to launch , if he calls from other application through Intent. That means my application should not respond to any intents from other outside Applications.
Is there any possible way to restrict my application's launch from intents from other application.?
I will be waitinig for reply.
Thanks in Advance,
Try setting android:exported="false" to all activities defined at AndroidManifest.xml
That's from activity element description:
android:exported Whether or not the activity can be launched by components of other applications — "true" if it can be, and "false" if not. If "false", the activity can be launched only by components of the same application or applications with the same user ID.
The default value depends on whether the activity contains intent filters. The absence of any filters means that the activity can be invoked only by specifying its exact class name. This implies that the activity is intended only for application-internal use (since others would not know the class name). So in this case, the default value is "false". On the other hand, the presence of at least one filter implies that the activity is intended for external use, so the default value is "true". This attribute is not the only way to limit an activity's exposure to other applications. You can also use a permission to limit the external entities that can invoke the activity (see the permission attribute).
Also here are good paragraphs about application permissions https://developer.android.com/training/articles/security-tips.html I guess you can use that to restrict access to your app.