应用沙盒

Android 平台利用基于用户的 Linux 保护机制来识别和隔离应用资源,可将不同的应用分离开,并保护应用和系统免受恶意应用的攻击。为此,Android 会为每个 Android 应用分配一个独一无二的用户 ID (UID),并在自己的进程中运行。

Android 会使用此 UID 设置一个内核级应用沙盒。内核会在进程级别利用标准的 Linux 机制(例如,分配给应用的用户 ID 和组 ID)实现应用和系统之间的安全防护。 默认情况下,应用不能彼此交互,而且对操作系统的访问权限会受到限制。例如,如果应用 A(一个单独的应用)尝试执行恶意操作,例如在没有权限的情况下读取应用 B 的数据或拨打电话,操作系统会阻止此类行为,因为应用 A 没有适当的用户权限。这一沙盒机制非常简单,可审核,并且基于已有数十年历史的 UNIX 风格的进程用户隔离和文件权限机制。

由于应用沙盒位于内核层面,因此该安全模型的保护范围扩展到了原生代码和操作系统应用。位于更高层面的所有软件(例如,操作系统库、应用框架、应用运行时环境和所有应用)都会在应用沙盒中运行。在某些平台上,为了执行安全防护机制,会限制开发者只能使用特定的开发框架、API 或语言。在 Android 上,并没有为此而限制开发者必须如何编写应用;在这方面,原生代码与解释型代码一样进行沙盒化。

保护机制

通常,要在经过适当配置的设备上攻破应用沙盒这道防线,必须要先攻破 Linux 内核的安全功能。但是,与其他安全功能类似,强制执行应用沙盒的各种保护机制并非无懈可击,因此深度防御对于防止通过单个漏洞入侵操作系统或其他应用非常重要。

Android 依靠许多保护机制来强制执行应用沙盒。 这些强制措施是随着时间的推移不断引入的,并且显著增强了基于 UID 的原始自主访问控制 (DAC) 沙盒的安全性。 以前的 Android 版本包括以下保护机制:

  • 在 Android 5.0 中,SELinux 提供了强制访问控制 (MAC) 来将系统和应用分离开。但是,所有第三方应用都在相同的 SELinux 环境中运行,因此应用间的隔离主要由 UID DAC 强制执行。
  • 在 Android 6.0 中,SELinux 沙盒经过扩展,可以跨各个物理用户边界隔离应用。此外,Android 还为应用数据设置了更安全的默认设置:对于 targetSdkVersion >= 24 的应用,应用主目录上的默认 DAC 权限从 751 更改为 700。这为私有应用数据提供了更安全的默认设置(但应用可能会替换这些默认设置)。
  • 在 Android 8.0 中,所有应用都设为使用 seccomp-bpf 过滤器运行,该过滤器可限制允许应用使用的系统调用,从而增强应用/内核边界的安全性。
  • 在 Android 9 中,targetSdkVersion >= 28 的所有非特权应用都必须在不同的 SELinux 沙盒中运行,并针对各个应用提供 MAC。这种保护机制可以提升应用隔离效果,防止替换安全默认设置,并且(最重要的是)防止应用的数据可让所有人访问。

共享文件指南

将应用数据设为可供所有人访问从安全方面来讲是一种不好的做法,因为这会为所有人授予访问权限,并且无法限定只让目标受众访问这些数据。这种做法会导致信息披露泄露,让代理漏洞变得混乱,并会成为针对包含敏感数据的应用(例如电子邮件客户端)的恶意软件的首选目标。在 Android 9 及更高版本中,targetSdkVersion>=28 的应用明确禁止以这种方式共享文件。

在共享文件时,请遵循以下指南,而不是让应用数据可供所有人访问: