Android is an OS designed for Smart phones. The phones are meant for office productivity apps, games, social networks etc. The phone comes pre-installed with a selection of system applications, e.g., phone dialer, address book, but the platform gives ample opportunities for the developers to create their own applications and publish into the huge android market, so called the “Play Store”.
With companies/enterprises supporting ‘BYOD’, the phones these days are full of sensitive data. As a platform, Android has its own security model which takes care of most of the things, but still there are cases where this security model itself has failed or people have misused some functionality/feature itself.One of the basic security measure is the Application sandbox in which each application runs in its own dalvik VM and cannot contact other running applications directly. Applications interact with each other and the phone through different forms of IPC. This article targets the android application developers and expects that the reader has some basic knowledge of some of terms like Activities,Intents,Services,Receivers, Content Providers.
Intents are typed interprocess messages that are directed to particular applications or systems services, or broadcast to applications subscribing to a particular intent type. Persistent content provider data stores are queried through SQL-like interfaces. Background services provide RPC and callback interfaces that applications use to trigger actions or access data. Finally user interface activities receive named action signals from the system and other applications. Binder acts as a mediation point for all IPC. Mentioned below are some of the basic security measured a android application developer should take care while coding an application.
Application needs prior approval to have access to things which might be restricted by default like, telephony, sms, and contacts. The permissions are stored in AndroidManifest.xml and user agrees to them upon install. Users won’t understand how their device works, so keep permissions simple and avoid technical terms like Binder, Activity or Intent when describing permissions to users.
Intents are the preferred mechanism for asynchronous IPC in Android.
Intents are used in many ways in android system. Using Context’s startActivity() method it can be used as broadcasts to inform interested programs of changes or events. Using Context’s sendBroadcast(), sendStickyBroadcast(), and sendOrderedBroadcast() family of methods as a way to start, stop or communicate with background Services. Using Context’s startService(), stopService(), and bindService() methods to access data through ContentProviders, such as the user’s contacts. Using Context’s getContentResolver() or Activities managedQuery() as call backs to handle events, like returning results or errors asynchronously with PendingIntents provided by clients to servers through their Binder interfaces
If you are sending Intent where delivery to a specific receiver is required, the intent must be delivered directly to the receiver, so they may not be delivered to all applications.
Senders of Intent can verify that the recipient has a permission specifying a non-Null Permission upon sending. Only applications with that Permission will receive the intent. If data within a broadcast intent may be sensitive, you should consider applying a permission to make sure that malicious applications cannot register to receive those messages without appropriate permissions. In those circumstances, you may also consider invoking the receiver directly, rather than raising a broadcast.
Broadcast receivers are used to handle asynchronous requests initiated via an intent. By default, receivers are exported and can be invoked by any other application. If your BroadcastReceivers is intended for use by other applications, you may want to apply security permissions to receivers using the <receiver> element within the application manifest. This will prevent applications without appropriate permissions from sending Intent to the BroadcastReceivers.
Activities are most often used for providing the core user-facing functionality of an application. By default, Activities are exported and invokable by other applications only if they have an intent filter or binder declared. In general, we recommend that you specifically declare a Receiver or Service to handle IPC, since this modular approach reduces the risk of exposing functionality that is not intended for use by other applications.
Activities cannot rely on IntentFilters (the <intent-filter> tag in AndroidManifest.xml) to stop callers from passing them badly configured Intents. Misunderstanding this is actually a relatively common source of bugs. On the other hand, Activity implementers can rely on permission checks as a security mechanism. Setting the android:permission attribute in an <activity> declaration will prevent programs lacking the specified permission from directly starting that Activity. Specifying a manifest permission that callers must have doesn’t make the system enforce an intent-filter or clean intents of unexpected values so always validate your input.
The following code demonstrates forcing the web browser’s Activity to handle and Intent with an action and data setting that aren’t permitted by its intent-filter:
// The browser's intent filter isn't interested in this action
Intent i = new Intent("Cat-Farm Aardvark Pidgen");
// The browser's intent filter isn't interested in this Uri scheme
// The browser activity is going to get it anyway!
If you run this code you will see the browser Activity starts, but the browser is robust and aside from being started just ignores this weird Intent.
Services are often used to supply functionality for other applications to use. Each service class must have a corresponding declaration in its package’s AndroidManifest.xml.
By default, Services are exported and can be invoked by any other application. Services can be protected using the android:permission attribute within the manifest’s <service> tag. By doing so, other applications will need to declare a corresponding <uses-permission> element in their own manifest to be able to start, stop, or bind to the service.
A Service can protect individual IPC calls into it with permissions, by calling checkCallingPermission() before executing the implementation of that call. We generally recommend using the declarative permissions in the manifest, since those are less prone to oversight.
Content Providers are used by applications to share raw data like SQL DATA, sounds, images. The <provider> tag in the applications AndroidManifest.xml registers a provider as available and defines permissions for accessing data. If you do not intend to provide other applications with access to your ContentProvider, mark them as ‘android:exported=false’ in the application manifest.
ContentProviders can also provide more granular access by declaring the grantUriPermissions element and using the FLAG_GRANT_READ_URI_PERMISSION and FLAG_GRANT_WRITE_URI_PERMISSION flags in the Intent object that activates the component. The scope of these permissions can be further limited by the grant-uri-permission element. When accessing a ContentProvider, use parameterized query methods such as query(), update(), and delete() to avoid potential SQL Injection from untrusted data. Note that using parameterized methods is not sufficient if the selection is built by concatenating user data prior to submitting it to the method.
Each application has its own area on the file system which it owns, almost like programs have a home directory to go along with their user ids. The mode parameter is used to create a file with a given set of file permissions. Avoid using MODE_WORLD_WRITABLE |MODE_WORLD_READABLE which makes a file world-readable and writable.
You can also encrypt files using a key (stored in KeyStore) that is not accessible to application.
Files created on external storage, such as SD Cards, are globally readable and writable. Since external storage can be removed by the user and also modified by any application, applications should not store sensitive information using external storage.
These were some of the very basic points which android application developers should take care while coding the applications. The points were too android specific, but developers should not forget the secure coding practices normally followed in the Web application development. Most of those will offcourse be used here too.
Ankur Bhargava is working as a Security Analyst in IBM ISL. Ankur’s area of interest are Web and Mobile Security. Ankur has presented in many of the security conferences and workshops like C0c0n(2010,2011), Nullcon 2012 on topics like PDF Exploits and Android Security.