Skip to content

Android's security models

We already know that Android is one of the most widely used operating systems today, but did you know that it also offers various security mechanisms to ensure that user data is as protected as possible?

Many of these mechanisms are inherited from the kernel on which Android is based: Linux; others were conceived at the very beginning of the platform's planning. Below I will list each of these mechanisms, discuss why they protect the user, and draw parallels with other platforms, such as personal computers.

The boot process and Rollback Prevention

Android's security already starts the first time the device is turned on by the user, where the entire boot chain, the process of turning on the phone, in which various services are initialized, is checked to ensure the integrity of the software to be run, but still leaves it up to the user to decide whether to allow a modified version of Android to be installed on their device, giving users greater freedom. It's worth remembering that the option of allowing the user to choose is up to the device manufacturer.

Each Android phone manufacturer (Google, Samsung, Motorola, etc.) has a cryptographic key that is used to sign the software that will be distributed on their phones. A device from the respective brand will only accept an Android version update if it can be validated that this signature is, in fact, from the manufacturer. This is the so-called root of trust.

In addition, for each new version installed on the device, the numerical value of that version is kept saved in an area that exists before any boot process, enabling the device itself to deny the installation of a version lower than the one currently present. This is called rollback prevention[2].

But why does this protect the user?

Imagine a scenario in which a privilege escalation vulnerability has been discovered in the Linux kernel, i.e. an attacker in possession of a vulnerable device could gain access to the root user, the super-powerful user in Linux.

However, the device in the attacker's possession contains a very recent version of Android. An alternative would be for him to install that vulnerable version we talked about earlier, but rollback prevention will ensure that this doesn't happen.

It's worth remembering that the user can dispense with these protections in order to install customized operating systems.

Binder

To understand what Binder is and why it is a key part of any Android device's security, we first need to understand how the first Android processes are created and segregated from each other.

At some point during the boot process, the Linux kernel will be booted, in the same way as on personal computers, in which the init.rc boot file will provide the necessary information for the boot process to take place correctly. One of these processes is the initialization of Android itself, the so-called framework, which can be understood as the system_server process, which will contain most of the essential services for the phone to work.

This process is very privileged in the Android environment and is responsible for a wide range of functions, from allowing access to certain directories, installing/uninstalling new applications, changing system settings and much more. It is also the process that can contact the kernel, either to request an exception or perform some validation, something that user processes (such as applications) are not allowed to do.

But what about when an application needs to open a file, for example?

In Linux, in order to deal with a file, it is necessary to ask the Kernel to prepare a read/write memory region where the file will be loaded. The Kernel is responsible for making this preparation and returning an object that identifies the file to the process that wants to use it.

In Android, all these requests have to be passed on to system_server , which will communicate with the Kernel. The same applies if application A wants to access something from application B, every request is made through the system_server, which in turn uploads the information about who is requesting it so that the kernel can validate whether application A has permission and finally make the request. This process is called IPC (inter-process communication).

To help with this back and forth journey, Binder was created, a structure responsible for associating each request with an application. In this way it is always possible to know who is requesting an action and to whom the result should be returned, ensuring that a malicious application cannot impersonate a legitimate application to access something it shouldn't.

Application Segregation

In Android, the application sandbox context is very strong. This is nothing more than locking each application in its own sandbox and, if one sandbox needs to access a resource in another sandbox, it needs to ask the system_server for permission.

Each application you have installed on your device is unavailable to the system until it is initialized. As soon as it is initialized (either by you clicking on the icon on the home page or via a link that the application registers) the kernel assigns a unique identifier to that application (its uid) and it becomes a live process.

At this point, on Android, process A doesn't even know that process B exists, the sandbox is so closed that you have to request everything through the system.

But in practice, how does this help user security?

Let's imagine two scenarios: (I) accessing internet banking from the browser of your personal computer with a Windows operating system and; (II) accessing the bank's application on your cell phone:

In (I) internet banking is run within the context of the browser, but there is no strong segregation between processes in Windows. If the user had malware, it would be able to read the entire memory of the browser process, seeing all the requests made to the server and any data that is clearly in memory.

In (II), the bank application will be "trapped" inside its own sandbox, i.e. it won't be able to communicate directly with other applications, but other processes won't be able to communicate directly with it either. This guarantees greater access control, since all communication requests must go through Android's privileged services.

Permissions

However, it is often necessary for an application to access system resources, such as external storage (/sdcard) or the camera. If each application is trapped in its own sandbox, how is this possible?

Again, we'll turn to system_server to guarantee access, but in these cases we'll need to understand the use of permissions.

Permissions are well-defined strings in the Android system that an application can define for the first time or declare that it uses them in its AndroidManifest.xml [3], a type of file that contains all the information relevant to the application's settings.

Each permission has a level of protection, the most common of which are: normal, which any application can declare it uses and the system will guarantee this use, dangerous, which is when you open the application and a little screen appears asking for your authorization to release the resource and signature, which can only be granted to applications that have the same signature as the application that declared the permission. In the next section, you'll learn more about what this signature is and how it works in this context.

In this way, we can say that an application that has never asked for your permission to use the resource will not be able to access your camera, for example.

Application signatures

In order to install an application, all of its code must be signed with a developer key.

In practice, each application development company has a set of cryptographic keys that are used to sign each code file, feature and configuration of an application. After this signature, the application loads metadata with a hash of the result of this signature for each file.

This is useful because it avoids the scenario where an attacker builds a malicious application with the same "name" (here "name" is used to designate the application's package name, a unique identifier for the application). However, since they won't have access to the key that signed the original application, they won't be able to generate the same signature for the application. When attempting to install this malicious version, if the user already has an original version of the application installed, the Android system will detect and deny the installation.

Recurring updates

Last but not least, it's common for Android device manufacturers to provide updates, either of Android versions or security patches.

No system is 100% secure and it is common for new vulnerabilities to be discovered in Android or any other operating system, but many manufacturers guarantee monthly system updates to correct these vulnerabilities.

Anyway, now we can get back to the subtitle of this blog post. Why do I feel safer using the bank app on my Android phone than internet banking on my personal computer?

Let's remember what was mentioned about Windows personal computers, for example: all processes run in the same context, are aware of other processes and can read/alter their memory, meaning that malware on a personal computer could see the memory of the process running internet banking and have access to its information. In other words, malware on a personal computer could see the memory of the process running internet banking.

Meanwhile, on Android, after carefully analyzing each of the security features described above, we can see that, even in a scenario where a user has a malicious application installed on their cell phone, they would still have Android system protections that this malware is trapped in its sandbox and would not be able to communicate with the bank's app, unless the bank has implemented some mechanism for this.

Finally, Android's security mechanisms are not limited to those mentioned above, there are still other mechanisms such as SELinux and Keystore, Trusted Execution Environment (TEE) which will be discussed in a future blogpost.

References

[1] https://source.android.com/security

[2] https://android.googlesource.com/platform/external/avb/+/master/README.md#Rollback-Protection

[3] https://developer.android.com/guide/topics/manifest/manifest-intro