blob: 1360161c520544d9867e8fca939af2183168e270 [file] [log] [blame]
<html devsite>
<head>
<title>Application Sandbox</title>
<meta name="project_path" value="/_project.yaml" />
<meta name="book_path" value="/_book.yaml" />
</head>
<body>
<!--
Copyright 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
//www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<p>
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.
</p>
<p>
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.
</p>
<p>
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.
</p>
<h2 id="protections">Protections</h2>
<p>
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.
</p>
<p>
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:
</p>
<ul>
<li>In Android 5.0, SELinux provided mandatory access control (MAC)
separation between the system and apps. However, all third-party apps ran
within the same SELinux context so inter-app isolation was primarily
enforced by UID DAC.</li>
<li>In Android 6.0, the SELinux sandbox was extended to isolate apps across
the per-physical-user boundary. In addition, Android also set safer defaults
for application data: For apps with <code>targetSdkVersion &gt;= 24</code>,
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).</li>
<li>In Android 8.0, all apps were set to run with a <code>seccomp-bpf</code>
filter that limited the syscalls that apps were allowed to use, thus
strengthening the app/kernel boundary.</li>
<li>In Android 9 all non-privileged apps with <code>targetSdkVersion &gt;=
28</code> 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.</li>
</ul>
<h2 id="guidelines-for-sharing-files">Guidelines for sharing files</h2>
<p>
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
<code>targetSdkVersion&gt;=28</code>.
</p>
<p>
Instead of making app data world-accessible, use the following guidelines when
sharing files:
</p>
<ul>
<li>If your app needs to share files with another app, use a <a
href="https://developer.android.com/guide/topics/providers/content-provider-basics.html">content
provider</a> or shared location on <a
href="https://developer.android.com/guide/topics/data/data-storage.html#filesExternal">external
storage</a>. Content providers share data with the proper granularity and
without the many downsides of world-accessible UNIX permissions (for
details, refer to <a
href="https://developer.android.com/guide/topics/providers/content-provider-basics.html">Content
provider basics</a>).</li>
<li>If your app has files that genuinely should be accessible to the world
(such as photos), use <a
href="https://developer.android.com/guide/topics/data/data-storage.html#filesExternal">external
storage</a>. For help, refer to <a
href="https://developer.android.com/training/data-storage/files.html#PublicFiles">Save
file to public directory</a>.</li>
</ul>
</body>
</html>