The Android platform takes advantage of the Linux user-based protection to identify and isolate app resources. This isolates apps from each other and protects apps and the system from malicious apps. To do this, Android assigns a unique user ID (UID) to each Android application and runs it in its own process.
Android uses this UID to set up a kernel-level Application Sandbox. The kernel enforces security between apps and the system at the process level through standard Linux facilities, such as user and group IDs that are assigned to apps. By default, apps can't interact with each other and have limited access to the operating system. For example, if application A tries to do something malicious, such as read application B's data or dial the phone without permission (which is a separate application), then the operating system protects against this behavior because application A does not have the appropriate user privileges. The sandbox is simple, auditable, and based on decades-old UNIX-style user separation of processes and file permissions.
Because the Application Sandbox is in the kernel, this security model extends to native code and to operating system applications. All of the software above the kernel, such as operating system libraries, application framework, application runtime, and all applications, run within the Application Sandbox. On some platforms, developers are constrained to a specific development framework, set of APIs, or language in order to enforce security. On Android, there are no restrictions on how an application can be written that are required to enforce security; in this respect, native code is as sandboxed as interpreted code.
Generally, to break out of the Application Sandbox in a properly configured device, one must compromise the security of the Linux kernel. However, similar to other security features, individual protections enforcing the application sandbox are not invulnerable, so defense-in-depth is important to prevent single vulnerabilities from leading to compromise of the OS or other apps.
Android relies on a number of protections to enforce the application sandbox. These enforcements have been introduced over time and have significantly strengthened the original UID-based discretionary access control (DAC) sandbox. Previous Android releases included the following protections:
targetSdkVersion >= 24
,
default DAC permissions on an app's home dir changed from 751 to 700. This
provided safer default for private app data (although apps may override
these defaults).seccomp-bpf
filter that limited the syscalls that apps were allowed to use, thus
strengthening the app/kernel boundary.targetSdkVersion >=
28
must run in individual SELinux sandboxes, providing MAC on a
per-app basis. This protection improves app separation, prevents overriding
safe defaults, and (most significantly) prevents apps from making their
data world accessible.
Setting app data as world accessible is a poor security practice as access is
granted to everyone and there is no way to limit access to only the intended
recipient(s). This practice has led to information disclosure leaks, confused
deputy vulnerabilities, and is a favorite target for malware that targets apps
with sensitive data (such as email clients). In Android 9 and higher, sharing
files this way is explicitly disallowed for apps with
targetSdkVersion>=28
.
Instead of making app data world-accessible, use the following guidelines when sharing files: