Broadcasts provide a way applications and system
components can communicate securely and efficiently. The messages are
sent as Intents, and the system handles dispatching them, including
starting receivers and enforcing permissions.
Receiving Broadcast Intents
Intents can be broadcast
to BroadcastReceivers, allowing messaging between applications. By
registering a BroadcastReceiver in your application’s AndroidManifest
.xml file, you can have your application’s receiver class started and
called whenever someone sends a broadcast your application is
interested in. Activity Manager uses the IntentFilter’s applications
register to figure out which program to use to handle a given
broadcast. As we discussed in the sections on IntentFilters and
Activity permissions, filters are not a security mechanism and can’t be
relied upon by Intent recipients. (IntentFilters can sometimes help
Intent sender safety by allowing the sending of an Intent that is
qualified by a category. Receivers that don’t meet the category
requirements won’t receive it, unless the sender forces delivery by
specifying a component. Senders adding categories to narrow deliver
therefore shouldn’t specify a component.) As with Activities, a
broadcast sender can send a receiver an Intent that would not pass its
IntentFilter just by specifying the target receiver component
explicitly. (See the examples given for Activities in the “Activities”
section. These examples can be applied to broadcasts by using
sendBroadcast() rather than startActivity() and adjusting the
components appropriately for your test classes.) Receivers must be
robust against unexpected Intents or bad data. As always, in secure IPC
programming, programs must carefully validate their input.
BroadcastReceivers
are registered in AndroidManifest.xml with the <receiver> tag. By
default they are not exported. However, you can export them easily by
adding an <intent-filter> tag (including an empty one) or by
setting the attribute android:exported=“true”. Once exported, receivers
can be called by other programs. Like Activities, the Intents that
BroadcastReceivers get may not match the IntentFilter they registered.
To restrict who can send your receiver an Intent, use the android:
permission attribute on the receiver tag to specify a manifest
permission. When
a permission is specified on a receiver, Activity Manager validates
that the sender has the specified permission before delivering the
Intent. Permissions are the right way to ensure your receivers only get
Intents from appropriate senders, but permissions don’t otherwise
affect the properties of the Intent that will be received.
Safely Sending Broadcast Intents
When sending a broadcast,
developers include some information or sometimes even a sensitive
object such as a Binder. If the data being sent is sensitive, they will
need to be careful who it is sent to. The simplest way to protect this
while keeping the system dynamic is to require the receiver to have
permission. By passing a manifest permission name (receiverPermission
is the parameter name) to one of Context’s broadcastIntent() family of
methods, you can require recipients to have that permission. This lets
you control which applications can receive the Intent. Broadcasts are
special in being able to very easily require permissions of recipients;
when you need to send sensitive messages, you should use this IPC
mechanism.
For example, an SMS
application might want to notify other interested applications of an
SMS it received by broadcasting an Intent. It can limit the receivers
to those applications with the RECEIVE_SMS permission by specifying
this as a required permission when sending. If an application sends the
contents of an SMS message on to other applications by broadcasting an
Intent without asserting that the receiver must have the RECEIVE_SMS
permission, then unprivileged applications could register to receive
that Intent, thus creating a security hole. Applications can register
to receive Intents without any special privileges. Therefore,
applications must require that potential receivers have some relevant
permission before sending off an Intent containing sensitive data.
Tip
It
is easier to secure implementing Activities than BroadcastReceivers
because Activities can ask the user before acting. However, it is
easier to secure sending a broadcast than starting an Activity because
broadcasts can assert a manifest permission the receiver must have.
Sticky Broadcasts
Sticky
broadcasts are usually informational and designed to tell other
processes some fact about the system state. Sticky broadcasts stay
around after they have been sent, and also have a few funny security
properties. Applications need a special privilege, BROADCAST_STICKY,
to send or remove a sticky Intent. You can’t require a permission when
sending sticky broadcasts, so don’t use them for exchanging sensitive
information! Also, anyone else with BROADCAST_STICKY can remove a
sticky Intent you create, so consider that before trusting them to
persist.
Tip
Avoid using sticky broadcasts for sharing sensitive information because they can’t be secured like other broadcasts can.