应用安全性最佳做法

本部分包含可确保 Android 设备上应用安全性的建议。

源代码审核

进行源代码审核可以发现大量安全问题,包括本文档中指出的问题。Android 强烈建议采用手动和自动两种方式审核源代码。

  • 在进行审核时,应遵循全面的安全指导以确保覆盖率。利用相关的内部或外部标准来确保一致且全面的审核。
  • 对所有使用 Android SDK 的应用代码运行 Linter(例如 Android Studio Liner),并更正发现的所有问题。
  • 使用可以发现内存管理问题(例如,缓冲区溢出和差一错误)的自动工具分析本机代码。
  • Android 编译系统支持很多 LLVM 清理程序,例如可用于对内存相关问题进行运行时分析的 AddressSanitizerUndefinedBehaviorSanitizer。如果与模糊测试配合使用(在 Android 中通过 libFuzzer 来实现),则清理程序可以发现需要进一步调查的异常极端情况。
  • 经验丰富的安全评估员应审核风险较高的代码,例如加密、付款处理和 PII 处理。

自动测试

自动测试功能有助于发现大量安全问题,且应定期执行。

  • 在整个开发流程中定期运行最新版 CTS,以便尽早发现问题并缩短解决问题所需的时间。在自动编译流程(每天会编译多次)的连续集成期间,Android 会使用 CTS。
  • 使接口的安全性测试实现自动化,包括使用格式有误的输入内容进行测试(模糊测试)。Android 编译系统支持使用 libFuzzer 来编写模糊测试。

漏洞扫描

漏洞扫描有助于确保预安装的应用不存在已知的安全漏洞。高级检测可以减少解决这些漏洞以及防止用户和设备面临风险所需的时间和成本。

  • 使用行业认可的应用漏洞扫描工具扫描所有预安装的应用,并解决检测到的漏洞。

潜在有害应用

请务必确保设备上的预安装应用不是潜在有害应用 (PHA)。您要为设备上安装的所有应用的行为负责。

恶意下载程序

恶意下载程序是指虽未被直接视为有害但会下载其他潜在有害应用的应用。

  • 确保针对所有使用 INSTALL_PACKAGES 权限的预安装应用提供用户披露功能。
  • 确保开发者遵守合同规定,未将任何应用作为 UID 0 进行安装。
  • 评估在通过开发者网络安装的所有应用清单中声明的权限。
  • 确保开发者遵守合同规定,在将应用提供给设备之前,使用 Google Safe Browsing API 扫描自动更新程序和安装程序应用的所有下载网址。
  • 从 Android 9 开始,要求所有开发者使用 UPDATE_PACKAGES 权限而非 INSTALL_PACKAGES 权限。与 INSTALL_SELF_UPDATES 结合使用时,使用 UPDATE_PACKAGES 可以根据特权应用的预期用途为其授予精细范围的安装权限(而不是更广泛的 INSTALL_PACKAGES 权限)。

挖矿

挖矿应用是指试图利用设备的硬件或云计算以“硬币”的形式生成货币(通常是通过区块链技术来实现)的应用。如果您打算将此服务作为货币的替代形式提供或使用这项服务交换其他服务,请确保在利用设备的硬件运行此服务之前请求获得用户的许可(包括明确同意这会影响电池运行时间)。

冒牌应用

冒牌应用是指试图将自己伪装成知名应用(例如 YouTube 或 Facebook)的应用。

  • 在设备发布之前,扫描所有预加载的应用以查找漏洞。

应用权限

为预安装应用授予过多权限可能会带来安全风险。尽可能减少为预安装应用授予的必要权限数量,并确保这些应用无法获取不必要的权限。

  • 不要为预安装的应用授予不必要的权限。仔细检查具有系统权限的应用,因为它们可能具有非常敏感的权限。
  • 确保请求的所有权限都是相关的,并且是使用该特定应用的功能所必需的。

应用签名

应用签名在保障设备安全方面发挥着重要作用,可用于进行权限检查以及软件更新。在选择为应用签名使用的密钥时,请务必考虑应用是仅在一台设备上使用,还是供多台设备共用。

  • 确保不使用众所周知的密钥(例如 AOSP 开发者密钥)为设备签名。
  • 确保按照与处理敏感密钥方面的业界标准做法一致的方式管理用于为应用签名的密钥,包括使用能够提供有限、可审核访问权限的硬件安全模块 (HSM)。
  • 确保不使用平台密钥为应用签名。这样做可以向应用授予平台签名权限,这些权限非常强大,只能由操作系统的一些组件使用。系统应用应使用特许权限。
  • 确保不使用不同的密钥为软件包名称相同的应用签名。在针对不同的设备开发应用时,经常会出现这种情况,尤其是在使用平台密钥时。如果应用独立于设备,则在多台设备之间使用相同的密钥。如果应用是特定设备专用的,则按设备和密钥创建独一无二的软件包名称。

隔离应用和进程

如果使用得当,Android 沙盒模型可为应用和进程提供额外的安全性。

隔离 Root 进程

Root 进程是最常受到提权攻击的目标,因此减少 Root 进程数量有助于降低提权风险。

  • 确保尽可能减少设备上作为 Root 代码运行的必要代码的数量。尽可能使用常规 Android 进程而非 Root 进程。如果某个进程必须要在设备上作为 Root 进程运行,请将该进程记录在 AOSP 功能请求中,以便对其进行公开审核。
  • 应尽可能将 root 代码与不可信数据隔离开来,并尽可能通过进程间通信 (IPC) 访问 Root 代码。例如,将 Root 功能缩减成可通过 Binder 访问的小型服务,并将这个具有签名权限的服务提供给网络流量处理权限很小或没有此类权限的应用。
  • Root 进程不得通过网络套接字进行监听。
  • Root 进程不得包含通用运行时(例如 Java 虚拟机)。

隔离系统应用

一般而言,预先安装的应用不应使用共用系统唯一标识符 (UID) 运行。如果某个应用必须使用共用系统 UID 或其他特权服务(例如,电话服务),那么该应用不应导出由用户安装的第三方应用可访问的任何服务、广播接收器或内容提供程序。

  • 确保尽可能减少设备上作为系统代码运行的必要代码的数量。尽可能通过 Android 进程自身的 UID 使用此类进程,而非重复使用系统 UID。
  • 应尽可能将系统代码与不可信数据隔离开来,并且系统代码应尽可能仅向其他可信进程提供 IPC。
  • 系统进程不得通过网络套接字进行监听。这是 CTS 要求。

隔离进程

Android 应用沙盒要求应用与系统中的其他进程(包括 Root 进程和调试程序)隔离开来。除非应用或用户特意启用了调试功能,否则任何应用都不得违反这一要求。

  • 确保 root 进程无法访问各个应用数据文件夹内的数据,使用已记录的 Android 调试方法时除外。
  • 确保 root 进程无法访问应用内存,使用已记录的 Android 调试方法时除外。
  • 确保设备上没有任何会访问其他应用/进程的数据或内存的应用。