Learn the basic concepts of Android app security: permissions, intent control, cryptography and keystores, and network security configuration
- Before looking at the security features built into all Android apps, let's take a deeper look at the four components of an app. An activity is the entry point for user interaction, and has an associated user interface screen. It can start another activity or service through an intent, and is used to manage navigation through the app. An activity goes through a number of states, and must declare call-backs to handle the transitions between them. The most common, the first one you see when creating an Android app, is the OnCreate function.
Other functions include OnStart, OnResume, OnPause, OnStop, OnRestart, and OnDestroy. The second component that may appear in an app is a service. These are long-running background operations which have no use interface. Like activities, services are declared in the manifest, and have call-back functions to control their transitions. They'll eventually call the StopSelf function to close down. A broadcast receiver component is used to send or receive broadcast messages from the Android operating system, or from other apps.
An app will register it's interest to receive a specific broadcast. For example, an SMS reading app must register to receive SMS messages. Whether it's sent an SMS message, then depends upon the form of intent used by the sending app. We'll cover this further when we talk about controlling intents. Broadcast receivers may be declared in the manifest file or may be dynamically created. There are three ways to send a broadcast; to one receiver at a time, to all receivers in an unspecified order, or just to receivers in the same app.
The final app component is the content provider for managing data store. This uses SQL-like methods for accessing data. An app doesn't need to use a content provider. It can open files directly, but it's good practice to do so. Data can be owned by the app, or an app may use data run by another app, or the operating system. The content provider manages data sharing. Applying access controls is required. Permissions are a key building block for security and Android apps.
There are many system permissions, as we can see in the Android reference documentation shown here. The Android system and applications own resources and data, and to access that, another application must make an explicit request by declaring the permissions they need. These include things like access to the camera, access to the microphone, access to the contact list, writing to external storage, and so on. The set-up system defined permissions cover most requirements, but applications can, however, define their own permissions.
In general, applications should minimize the permissions they need. An application declares the permissions it needs in it's Android manifest file. Permissions are grouped into four protection levels. Normal protection level permissions are for little risk, and are able to be approved automatically at installation. Dangerous protection level permissions are those which enable access to private information on the device, or have access to capabilities which could be misused. These require explicit user agreements.
The operating system approves signature protection level permissions only if the requesting application is signed with the same certificate as the application that declared the permission. This approval is automatic. The signatureOrSystem protection level extends the signature level by also allowing system apps to be approved. This level is reserved for special types of manufacturer permissions, and is not intended to be used by developers. Permissions mainly provide protection for users to have control over the capabilities an app uses, however, by using custom permissions, the developer can limit access to application components to other components or apps that they control.
This can be a useful feature, particularly for exported activities or services. However, there is a risk in using this. An issue known as The Custom Permission Problem. Which can allow a malicious app to gain access. I won't describe this in detail, but you can read further about the issue here. This was resolved in Android 5.0. Android uses a technique called intents to achieve inter-process communication. An intent is a message requesting an action, and optionally providing data to another component.
This component can be an internal activity, or an external activity that has been flagged for export from its application. Android provides two ways of calling an intent; either explicitly or implicitly. An explicit intent indicates the target application and component to use by specifying its Java class. An implicit intent lets the Android operating system decide which component will service the request. One use of intents is to start an activity by sending a start activity intent.
The intent may include data, and the activity may return data. Here we see activity A calling activity B explicitly via an intent, and using the putExtra method to include data as a call argument. A component that wants to process requests sent via an implicit intent will specify an intent filtered to indicate the type of intent that it can respond to. For instance, an application may specify an intent filter for an SMS message. And so, indicate to the Android operating system that it can be considered as a candidate to respond to an incoming SMS.
Here we see an intent implicitly requesting that a web page be displayed by pointing at the location of the webpage using the setData method. The Android system will search for all components, which are registered for the specific action, and the fitting data time. If only one component is found, Android starts this component directly. If several components are identified by the Android system, the user will get a selection dialogue, and can decide which component should be used for the intent.
A service is started by sending a startService intent. Here we see an activity starting its status monitoring service. This could be a service which allows other activities to asynchronously check the status of the activity. Here's an example of sending a message via an application broadcast as an implicit intent. This also sets a flag on the intent to specify that it may also start a package if it's not running. There are, in fact, three ways to specify how a broadcast is to be processed; to one receiver at a time, to all receivers in an unspecified order, or just to receivers in the same app.
In this case, we're taking the default of unspecified order. Given the loosely connected nature of Android components, it's important that intents are used securely. We've already seen the use of explicit intents, which provide good control over what component may action your intent. Android provides other security features around intents. For example, an activity may want to limit which activities can start it. You can do this using a custom permission. Then, only those apps with that permission granted may issue an intent to start the activity.
In addition, if an app has set the signature protection level, only other apps that are assigned with the same key can issue an intent to an exported activity or service in that app.
- Understanding Android OS, app, and hardware security components
- Using the Trusted Execution Environment
- Developing Android apps with security in mind
- Analyzing existing applications
- Understanding Android vulnerabilities
- Securing Android apps
- Developing secure enterprise apps