How to limit broadcast to its own Android app - android

I wondering if it is possible to create a private broadcast.
I actually register broadcastreceiver in my activity and use
sendOrderedBroadcast(broadcast);
method to send the broadcast.
But, for now, the intent (broadcast) used for this method is defined like this :
Intent broadcast = new Intent("com.mypackage.broadcast");
So every external application which declare this package name can listen what I am sending, and I don't want to.
So how to make this impossible, that no one can listen my broadcast ?

I think you are looking for LocalBroadcast Manager. The docs say:
It is a helper to register for and send broadcasts of Intents to local objects within your process. This is has a number of advantages over sending global broadcasts with sendBroadcast(Intent). One of them is that the data you are broadcasting won't leave your app, so don't need to worry about leaking private data.`
See how to use LocalBroadcastManager? for more. Hope it helps you.

For LocalBroadcast Manager to work the app should be running.
To have a generic strategy to limit Android broadcasts to your own app only, we can do as follow.
Intent intent = new Intent();
String packageName = context.getApplicationContext().getPackageName();
intent.setAction(packageName + "<MY_ACTION>");
context.sendBroadcast(intent);
Since the application package would remain unique for all apps on android, this would safely limit the Broadcast to your own app and you can register BroadcastReceivers in AndroidManifest.xml.

Related

How to get intent filter and application name through a broadcast

I need to know if there is a way to obtain the intent filter of an applicaction (activity) and the actual name of the application as we see it on the android launcher screen, through a broadcast it sends to a service.
The service receives the broadcast through its broadcast receiver, then it needs to know the applicatione's name and its intent filter in order to do some work with that information. Is there a way to find this out through the intent, or does the application need to actually putextras in the intent?
Is there a way to find this out through the intent
Not really, insofar as the Intent has no information about the Intent's origination point.
does the application need to actually putextras in the intent?
Yes, because only the originator of the broadcast knows what is appropriate to be used. After all, an app may have zero, one, or many launcher activities.
You're welcome to try the getCallingUid() and/or getCallingPid() static methods on Binder, to try to automatically derive who the sender is, but this may not work well if there are multiple apps that are using sharedUserId on the device.

Can I use `intent.setClassName()` to limit a broadcast sending?

I was sending a broadcast like below:
Intent intent = new Intent();
intent.setAction(com.test.CHANGE_MESSAGE_COUNT);
intent.putExtra("count", 1);
context.sendBroadcast(intent);
But someone says I'm having some security problem, and I should use intent.setClassName, so that my intent can not be hijacked.
So I modified my code, added a line:
Intent intent = new Intent();
intent.setAction(com.test.CHANGE_MESSAGE_COUNT);
intent.setClassName(context, "NotExistingClass");
intent.putExtra("count", 1);
context.sendBroadcast(intent);
I found that even I set a class name not ever exist, I can still recieve the broadcast, which means my intent can still be hijacked.
So I wonder if there is something wrong with my code or that setClassName just can be used in starting a activity but not in sending a broadcast?
I think you're looking for Intent.setPackage() which will limit the app that can receive the broadcast to having that package name.
[EDIT] Also consider using a LocalBroadcastManager if you're broadcasting in the same process that your receiver resides in
You could use LocalBroadcastManager to resolve this issue. I list descpritons in google develop docs about this class:
Helper to register for and send broadcasts of Intents to local objects within your process. You know that the data you are broadcasting won't leave your app, so don't need to worry about leaking private data.
It is not possible for other applications to send these broadcasts to your app, so you don't need to worry about having security holes they can exploit.
It is more efficient than sending a global broadcast through the system.

Aletrnative solution for LocalBroadcastManager

How to achieve the LocalBroadcastManager functionality using the normal broadcasts programmatically without keeping any thing in the manifest. My goal is to limit my broadcast scope to my own application.
To broadcast an Intent within your application's context then LocalBroadcastManager is the safest way to do it. However, if you want to achieve the similar functionality via ordinary broadcast procedures then you may explicitly define a package which should listen your broadcast. For example:
Intent intent = new Intent("com.abc.my_action");
intent.setPackage("com.package.other"); //Set an explicit application package
sendBroadcast(intent);
This restriction for broadcasts is available in ICS and onwards. For more info read this.
P.S. I would still recommend you to stick with LocalBroadcastManager as it broadcasts intents within your application's context and is considered to be the safest.

In Android: Can I receive a Broadcast intent from one application into second application

I have an application Application1 which contains 2 java classes Sender (for sending a Broadcast intent) and Receiver (for receiving the Broadcast intent broadcasted by Sender).
So can I receive the intent broadcasted by Sender of Application1 in a Receiver class of an other application, let suppose Applications2? Is it possible to receive the intent broadcasted by one application into an other application?
the answer is - yes, you can. BroadcastReceiver is the right (and only trivial) way passing data between applications. no problem broadcasting intent from application1 and receive it with the appropriate intent filter in application2. furthermore - Google recommends doing so.
one thing you need to know - your intent filter should be unique, and not easy to guess by malicious apps want to intercept some private user's data you don't want to share with them.

Is it possible to scope a broadcast to an application?

I want to use sendBroadcast to broadcast an intent that can only be received by that application that originated it.
The use case is for an authentication module I'm planning to use between several projects I've built. Currently when a 401 (authorization failed) response code is received it broadcasts an intent that can then be wired in the manifest to bring the user back to the login page.
So just to be clear I'm wondering if I can do this:
Intent i = new Intent("my.custom.logout.broadcast.path.that.will.be.the.same.in.multiple.apps");
sendBroadcast(i);
And somehow the intent doesn't get picked up by other apps that use exactly the same un-modified code base.
Not part of the question, but you should be using permissions for restricting who can send/receive the Broadcasts, especially since you're dealing with authentication. In fact, I would highly recommend looking into the AccountManager (in API demos)
Moving on.. one solution is to pass the originating application's package name or a particular permission string in an Intent extra, and when you respond, use that package name or permission in the response, the same way. Unfortunately you can't target a specific package in a Broadcast Intent.
Yet another solution, is using PendingIntent.getActivity() from the originating application, stuff that PendingIntent into the new for-broadcast Intent as an extra (Intent#putExtra()) and broadcast it using the permissions model above (so sender and receiver can handle permissions properly). When the broadcast receiver has finished doing its thing, it can use the PendingIntent to start the target activity (including the ability to attach additional extras)
For this you can use the LocalBroadcastManager, which is specifically designed for in-app communication.

Categories

Resources