Android 安全团队经常会收到用户发来的请求,希望我们提供关于如何防止 Android 设备上出现潜在安全问题的信息。我们偶尔也会对设备进行抽查,并让设备制造商和受影响的合作伙伴知晓潜在问题。
在本页中,我们提供了根据自己的经验总结的安全方面的最佳做法(扩展了我们为开发者提供的安全设计文档),以及关于如何在设备上编译或安装系统级软件的详细信息。
为了方便相关人员采用这些最佳做法,Android 安全团队会尽可能将相关测试整合到 Android 兼容性测试套件 (CTS) 和 Android Lint 中。我们竭诚欢迎设备实现人员贡献可以帮助其他 Android 用户的相关测试(要查看与安全相关的测试,请访问 root/cts/tests/tests/security/src/android/security/cts
)。
请在开发流程和环境中遵循以下最佳做法。
进行源代码审核可以发现大量安全问题,包括本文档中指出的问题。Android 强烈建议采用手动和自动两种方式审核源代码。最佳做法:
自动测试功能可以发现大量安全问题,包括下文中讨论的一些问题。最佳做法:
系统映像的签名对于判断设备的完整性至关重要。最佳做法:
应用签名在保障设备安全方面发挥着重要作用,可用于进行权限检查以及软件更新。在选择为应用签名使用的密钥时,务必要考虑应用是仅在一台设备上使用,还是供多台设备共用。最佳做法:
在 Google Play 中,设备制造商能够直接更新应用,而无需进行完整的系统更新。这不仅有助于加快应对安全问题和推出新功能的速度,还有助于确保您的应用具有独一无二的软件包名称。最佳做法:
外部各方必须能够就设备特有的安全问题与设备制造商联系。我们建议创建一个公开的电子邮件地址来管理安全事件。最佳做法:
在实现产品时,请遵循以下最佳做法。
Root 进程是最常受到提权攻击的目标,因此减少 Root 进程数量有助于降低提权风险。CTS 中包含一个能够列出 Root 进程的信息测试。最佳做法:
一般而言,预先安装的应用不应使用共用系统 UID 运行。不过,如果某个应用必须使用共用系统 UID 或其他特权服务(例如,电话服务),那么该应用不应导出由用户安装的第三方应用可访问的任何服务、广播接收器或内容提供程序。最佳做法:
Android 应用沙盒要求应用与系统中的其他进程(包括 Root 进程和调试程序)隔离开来。除非应用或用户特意启用了调试功能,否则任何应用都不应违反这一要求。最佳做法:
新的 SetUID 程序应该不能被不可信程序访问。SetUID 程序过去经常是可被用来获取 Root 权限的漏洞位置,因此务必要最大限度地降低 SetUID 程序对不可信应用的可用性。最佳做法:
CTS 验证程序包括一个可列出 SUID 文件的信息测试;根据 CTS 测试,有些 SetUID 文件是不允许使用的。
当设备通过任何端口或任何接口进行监听时,CTS 测试都会失败。如果测试失败,Android 会验证是否遵循了以下最佳做法:
记录数据的做法会增加数据遭泄露的风险并降低系统性能。之前曾发生过多起因 Android 设备上默认安装的应用记录敏感用户数据而导致的公共安全事件。最佳做法:
CTS 中包含一些能够检查系统日志中是否存在可能敏感的信息的测试。
全局可写目录可能会引入安全漏洞,并且可能会使应用能够重命名可信文件、替换文件或进行基于符号链接的攻击(攻击者可能会利用指向某个文件的符号链接诱使可信程序执行不应执行的操作)。可写目录还可能会导致卸载应用后无法适当清除与相应应用关联的所有文件。
作为最佳做法,系统用户或 Root 用户创建的目录不应为全局可写目录。CTS 测试能够测试已知目录,从而有助于强制执行这种最佳做法。
许多驱动程序和服务都依赖于存储在 /system/etc
、/data
等目录中的配置文件和数据文件。如果这些文件由某个特权进程处理且为全局可写文件,应用可能能够通过在全局可写文件中创建恶意内容来利用该特权进程中的漏洞。最佳做法:
特权设备制造商进程使用的所有代码都必须位于 /vendor
或 /system
中;这些文件系统会在设备启动时以只读模式装载。作为最佳做法,系统使用的库或手机上安装的其他权限非常高的应用使用的库也应位于这些文件系统中。这有助于防止出现可让攻击者用来控制特权进程执行的代码的安全漏洞。
应该只有可信代码能够直接访问驱动程序。首选架构要尽可能提供一个单一用途守护进程来代理向驱动程序发出的调用,并仅限该守护进程访问驱动程序。作为最佳做法,驱动程序设备节点不应为全局可读或全局可写节点。CTS 测试能够检查是否存在全局可读或全局可写驱动程序的已知实例,从而有助于强制执行这种最佳做法。
Android 调试桥 (ADB) 是一款非常实用的开发和调试工具,但它只适合在受控的安全环境中使用,不应针对一般使用情况启用该工具。最佳做法:
许多 Android 设备都支持解锁引导加载程序。解锁引导加载程序后,设备所有者将能够修改系统分区和/或安装自定义操作系统。常见用例包括在设备上安装第三方 ROM 以及进行系统级开发。例如,Google Nexus 设备所有者可以运行 fastboot oem unlock
来启动解锁过程,该进程会向用户显示以下消息:
Unlock bootloader?
If you unlock the bootloader, you will be able to install custom operating system software on this phone.
A custom OS is not subject to the same testing as the original OS, and can cause your phone and installed applications to stop working properly.
To prevent unauthorized access to your personal data, unlocking the bootloader will also delete all personal data from your phone (a "factory data reset").
Press the Volume Up/Down buttons to select Yes or No. Then press the Power button to continue.
Yes: Unlock bootloader (may void warranty)
No: Do not unlock bootloader and restart phone.
作为最佳做法,在解锁之前,可解锁的 Android 设备必须先安全地清除所有用户数据。如果未能适当删除所有数据便进行解锁,能够接触到这些设备的攻击者便可以在未经授权的情况下获取机密的 Android 用户数据。为了防止用户数据泄露,支持解锁的设备必须正确实现解锁(我们已见到过设备制造商以不当方式实现解锁的无数实例)。正确实现的解锁过程具有以下特性:
unlocked
标记。ioctl(BLKSECDISCARD)
或等同命令,则应使用此类命令。对于 eMMC 设备,这意味着使用 Secure Erase 或 Secure Trim 命令。对于 eMMC 4.5 及更高版本,这意味着先使用常规的 Erase 或 Trim 命令,然后再执行 Sanitize 操作。BLKSECDISCARD
,则必须改用 ioctl(BLKDISCARD)
。在 eMMC 设备上,这是一个常规的 Trim 操作。BLKDISCARD
不受支持,可以将块设备中的数据重写为全零。fastboot oem lock
命令来实现。这些要求旨在确保在完成解锁操作时所有数据都已被销毁。未能实现这些保护措施会被视为存在中级安全漏洞。
将设备解锁后,可以使用 fastboot oem lock
命令重新将其锁定。使用新的自定义操作系统时,锁定引导加载程序能够为用户数据提供的保护与原始设备制造商操作系统提供的保护相同(例如,如果设备被再次解锁,用户数据将会被清除)。