应用安全

应用元素

Android 提供了一个适用于移动设备的开放源代码平台和应用环境。核心操作系统基于 Linux 内核。Android 应用通常都是使用 Java 编程语言编写的,并在 Dalvik 虚拟机中运行。不过,也可以使用原生代码编写应用。应用是通过文件扩展名为 .apk 的单个文件安装的。

Android 应用的主要构建块包括:

  • AndroidManifest.xmlAndroidManifest.xml 文件是一个控制文件,用于告诉系统如何处理应用中的所有顶层组件(具体来说就是下面介绍的 activity、service、broadcast receiver 和 content provider)。该文件还用于指定需要哪些权限。

  • ActivityActivity 通常是指面向用户的单个任务的代码,通常包括向用户显示界面,但也并非一定如此,有些 activity 就从不显示界面。通常情况下,应用的入口点是应用的某一个 activity。

  • serviceservice 是指在后台运行的一段代码。service 可以在自己的进程中运行,也可以在另一应用的进程中运行。其他组件会“绑定”到某项服务,并通过远程过程调用来调用该服务的方法。比如媒体播放器就是一项服务:即使用户退出媒体选择界面,大概也仍然希望音乐继续播放。即使界面已关闭,service 也可使音乐继续播放。

  • Broadcast ReceiverBroadcastReceiver 是一种对象,该对象会在操作系统或另一应用发出称为 intent 的 IPC 机制时实例化。例如,应用可以注册一个接收器来接收电量不足的消息,并可以根据该信息改变自己的行为。

Android 权限模型:访问受保护的 API

Android 上的所有应用均在应用沙盒内运行。默认情况下,Android 应用只能访问有限的系统资源。系统负责管理 Android 应用对资源的访问权限。如果资源使用不当或被恶意使用,可能会给用户体验、网络或设备上的数据带来不利影响。

这些限制是通过多种不同的形式实现的。有些功能会因 Android 有意未提供敏感功能的 API(例如,Android 中没有用于直接操控 SIM 卡的 API)而受到限制。在某些情况下,角色分离能够提供一种安全措施,就像按应用隔离存储空间一样。在其他情况下,敏感 API 旨在供可信应用使用,并由一种称为“权限”的安全机制进行保护。

这些受保护的 API 包括:

  • 摄像头功能
  • 位置数据 (GPS)
  • 蓝牙功能
  • 电话功能
  • 短信/彩信功能
  • 网络/数据连接

这些资源只能通过操作系统进行访问。如需使用设备上受保护的 API,应用必须在其清单中定义所需的功能。所有 Android 6.0 版本及更高版本均会使用运行时权限模式。如果用户请求使用一款需要受保护 API 的应用的某项功能,系统会向用户显示一个对话框,提醒用户拒绝允许授予相关权限。

获得授权后,应用只要已安装在设备上,便会一直拥有这些权限。为了避免用户混淆,系统不会再次通知用户向应用授予的权限,而核心操作系统中包含的应用或由原始设备制造商 (OEM) 预装的应用不会向用户申请权限。应用卸载后,权限也会被移除,因此如果用户之后重新安装卸载的应用,系统会再次显示应用申请的权限。

在设备设置中,用户可以查看之前安装的应用的权限。此外,用户还可以根据需要在全局范围内停用某些功能,例如停用 GPS、无线功能或 Wi-Fi。

如果应用尝试使用未在其清单中声明的受保护功能,权限失败通常会导致系统向应用抛回一个安全异常。受保护 API 权限检查会在最底层被强制执行,以防止出现规避行为。图 2 中显示了如果应用在安装时申请受保护 API 的访问权限,会导致系统向用户显示的消息示例。

如需了解有关系统默认权限的信息,请访问:https://developer.android.com/reference/android/Manifest.permission.html。 应用可以声明自己提供的权限,以供其他应用使用。上述页面中未列出此类权限。

在定义权限时,protectionLevel 属性用于告诉系统如何让用户知道哪些应用需要或可以获得相应权限。如需详细了解如何创建和使用应用特有权限,请访问:https://developer.android.com/guide/topics/security/security.html

有些设备功能(例如,发送短信广播 Intent 的功能)不会供第三方应用使用,但可供原始设备制造商 (OEM) 预装的应用使用。这些应用使用 signatureOrSystem 权限。

用户如何了解第三方应用

当用户与第三方应用互动时,Android 会尽力让用户清楚这一情况,并让用户知道这些应用具备的功能。在安装任何应用之前,系统都会向用户显示一条明晰的消息,让用户知道要安装的应用申请获得的各项权限。安装完毕后,系统不会再次提示用户确认任何权限。

在安装前一刻显示权限的原因有很多。这时用户正在主动查看应用、开发者和功能方面的信息,以确定其是否符合自己的需求和期望。同样非常重要的一点是,他们尚未对要安装的应用做出心理或财务方面的承诺,并且可以轻松地将要安装的应用与其他替代应用进行比较。

有些其他平台会使用不同的方式通知用户,即在每个会话开始时或用户正在使用应用时申请权限。Android 的愿景是让用户能够随意在应用之间无缝切换。每次都要求用户确认会拖慢用户的操作速度,而且会导致 Android 无法提供良好的用户体验。如果让用户在安装应用时查看权限,用户便可以在不愿意授予权限时选择不予安装。

此外,许多人机界面研究表明,过度提示用户会导致用户在看到任何对话框时都选择“确定”。Android 的安全目标之一是向用户有效地传达重要的安全信息,而使用让用户习惯性忽略的对话框则无法做到这一点。如果只向用户提供一次重要信息并且仅在重要时刻提供,用户更有可能慎重思考他们要同意的是什么。

有些平台会选择完全不显示与应用功能有关的任何信息。这种方式会导致用户无法轻松了解和讨论应用功能。尽管无法使所有用户始终都在已充分了解相关信息的情况下做出决定,但 Android 权限模式让众多用户能够轻松获取与应用相关的信息。例如,如果遇到意外的权限申请,经验更丰富的用户可能会提出有关应用功能的质问,并在 Google Play 等所有用户都可以看到的位置分享他们的疑问。

应用安装时显示权限 - Google 地图 应用安装后显示权限 - Gmail
应用安装时显示权限 - Google 地图 应用安装后显示权限 - Gmail

图 1. 应用所需权限的显示方式

进程间通信

进程可以使用 UNIX 类型的任何传统机制进行通信。例如,文件系统、本地套接字或信号。不过,Linux 权限仍然适用。

Android 还提供了一些新的 IPC 机制:

  • binder:一种基于功能的轻量型远程过程调用机制,在执行进程内调用和跨进程调用时能够实现出色的性能。binder 是使用自定义 Linux 驱动程序实现的。详见 https://developer.android.com/reference/android/os/Binder.html

  • service:service(如上文所述)可提供能够使用 binder 直接访问的接口。

  • intent:intent 是简单的消息对象,表示想执行某项操作的“意图”。例如,如果您的应用想显示某个网页,则会创建一个 intent 实例并将其传递给系统,以此来表示想访问相应网址的“意图”。然后,系统会找到一些知道如何处理该 Intent 的其他代码(在本例中为浏览器),然后运行该代码。intent 也可用于在系统范围内广播有趣的事件(例如通知)。详见 https://developer.android.com/reference/android/content/Intent.html

  • ContentProvider:ContentProvider 是一个数据存储库,用于访问设备上的数据;典型的示例就是用于访问用户通讯录的 ContentProvider。应用可以访问其他应用通过 ContentProvider 提供的数据,还可以定义自己的 ContentProvider 来提供自己的数据。详见 https://developer.android.com/reference/android/content/ContentProvider.html

虽然可以使用其他机制(例如,网络套接字或全局可写文件)来实现 IPC,但上面这些都是建议使用的 Android IPC 框架。建议 Android 开发者遵循保护用户数据及避免引入安全漏洞方面的最佳实践。

费用敏感 API

费用敏感 API 指可能会给用户或网络带来费用的任何功能。Android 平台已将费用敏感 API 放入由操作系统控制的受保护 API 列表中。如果有第三方应用申请使用这些 API,必须要由用户明确授权,它们才能使用这些 API。这些 API 包括:

  • 电话
  • 短信/彩信
  • 网络/数据
  • 应用内结算
  • NFC 访问

Android 4.2 进一步增强了对使用短信的控制。如果有应用尝试向使用付费服务的短号码发送短信(可能会产生额外的费用),Android 将会通知用户。用户可以选择是允许还是阻止该应用发送短信。

SIM 卡访问

第三方应用无法对 SIM 卡进行底层访问。操作系统负责处理与 SIM 卡之间的所有通信,包括访问 SIM 卡内存中的个人信息(通讯录)。应用也无法访问 AT 命令,因为这些命令完全由无线接口层 (RIL) 进行管理。RIL 不会为这些命令提供任何高层 API。

个人信息

Android 已将能够用于访问用户数据的 API 放入受保护 API 组中。在正常使用期间,Android 设备还会收集用户安装的第三方应用内的用户数据。选择分享这些信息的应用可以使用 Android OS 权限检查功能保护来自第三方应用的数据。

只能通过受保护的 API 访问敏感的用户数据

图 2. 只能通过受保护的 API 访问敏感的用户数据

可能包含个人信息或个人身份信息(例如,通讯录和日历)的系统内容提供程序在创建时便已拥有明确确定的权限。这种精细的设计可让用户清楚地知道哪些类型的信息可能会提供给相应应用。在安装过程中,第三方应用可能会申请这些资源的访问权限。获得授权后,应用便可以进行安装,并且只要安装在设备上,便会一直有权访问最初申请访问的数据。

默认情况下,收集个人信息的所有应用都会仅限特定应用访问这些数据。如果某个应用选择通过 IPC 将数据提供给其他应用,那么这个授予访问权限的应用便可以限制由操作系统强制执行的 IPC 机制的权限。

敏感数据输入设备

Android 设备经常会提供可让应用与周围环境进行互动的敏感数据输入设备(例如,摄像头、麦克风或 GPS)。对于要使用这些设备的第三方应用,必须先由用户通过使用 Android OS 权限向其明确提供使用权限。安装应用时,安装程序会以提供名称的方式请用户授予使用相应传感器的权限。

如果某个应用想要知道用户所在的位置,则需要获得获取用户位置信息的权限。安装应用时,安装程序会询问用户是否允许该应用获取用户的位置信息。如果用户不希望任何应用获取其位置信息,可以随时运行“设置”应用,转到“位置和安全”,然后取消选中“使用无线网络”和“启用 GPS 卫星”。这将针对用户设备上的所有应用停用需要使用位置信息的服务。

设备元数据

Android 还会尽力限制访问本身并不属于敏感数据,但可能会间接透露用户特征、用户偏好以及设备使用方式的数据。

默认情况下,应用无权访问操作系统日志、浏览器历史记录、电话号码以及硬件/网络标识信息。如果应用在安装时申请此类信息的访问权限,安装程序会询问用户是否允许该应用访问此类信息。如果用户没有授予该权限,系统将不会安装应用。

证书授权机构

Android 中收录了一组预载的系统证书授权机构 (CA),这些授权机构在整个系统范围内受到信任。在 Android 7.0 之前的版本中,设备制造商可以修改其设备上搭载的 CA 组。不过,搭载 7.0 及更高版本的设备将具有一组统一的系统 CA,并且不再允许设备制造商对其进行修改。

若要作为新的公共 CA 添加到 Android 收录的 CA 组中,相应 CA 必须完成 Mozilla CA 收录流程,然后提交一项针对 Android 的功能请求 (https://code.google.com/p/android/issues/entry),以便申请将其添加到 Android 开源项目 (AOSP) 收录的 Android CA 组中。

此外还有一些设备专用 CA,这些 CA 不应被收录到 AOSP CA 核心组中,例如,安全访问运营商基础架构组件(例如,短信/彩信网关)时可能需要的运营商私有 CA。建议设备制造商将私有 CA 仅收录在需要信任这些 CA 的组件/应用中。如需了解详情,请参阅网络安全配置

应用签名

通过代码签名,开发者可以标识应用创作者并更新自己的应用,而无需创建复杂的接口和权限。在 Android 平台上运行的每个应用都必须要有开发者的签名。Google Play 或 Android 设备上的软件包安装程序会拒绝没有获得签名就尝试安装的应用。

在 Google Play 上,应用签名可以将 Google 对开发者的信任和开发者对自己的应用的信任联系在一起。开发者知道自己的应用是以未经修改的形式提供给 Android 设备的,并且可对该应用的行为负责。

在 Android 上,应用签名是将应用放入其应用沙盒的第一步。已签名的应用证书定义了哪个用户 ID 与哪个应用相关联;不同的应用要以不同的用户 ID 运行。应用签名可确保一个应用无法访问任何其他应用,通过明确定义的 IPC 进行访问时除外。

当应用(APK 文件)安装到 Android 设备上时,软件包管理器会验证 APK 是否已经过适当签名(已使用 APK 中包含的证书签名)。如果该证书(或更准确地说,证书中的公钥)与为设备上的任何其他 APK 签名时使用的密钥一致,那么这个新 APK 可以选择在清单中指定它将与其他以类似方式签名的 APK 共用一个 UID。

应用可以由第三方(原始设备制造商 (OEM)、运营商、其他应用市场)签名,也可以自行签名。Android 提供了使用自签名证书进行代码签名的功能,而开发者无需外部协助或许可即可生成自签名证书。应用并非必须由核心机构签名。Android 目前不对应用证书进行 CA 认证。

应用还可以在“签名”保护级别声明安全权限,以便仅限使用同一个密钥签名的应用访问它们,同时维持单独的 UID 和应用沙盒。通过共用 UID 功能,可以与共用的应用沙盒建立更紧密的联系,这是因为借助该功能,使用同一个开发者密钥签名的两个或更多应用可以在其清单中声明共用的 UID。

应用验证

Android 4.2 及更高版本均支持应用验证。用户可以选择启用“验证应用”,并在安装应用之前使用一款应用验证程序来评估应用。如果用户尝试安装的应用可能有害,应用验证功能可以提醒用户;如果应用的危害性非常大,应用验证功能可以阻止安装。

数字版权管理

Android 平台提供了一个可扩展的 DRM 框架,以便应用根据与受版权保护的内容相关的许可限制条件来管理这些内容。DRM 框架支持多种 DRM 方案;设备具体支持哪些 DRM 方案由设备制造商决定。

Android DRM 框架是在两个架构层中实现的(请看下图):

  • DRM Framework API:通过 Android 应用框架提供给应用,并通过适用于标准应用的 Dalvik VM 运行。

  • 原生代码 DRM 管理器:用于实现 DRM 框架,并为 DRM 插件(代理)提供接口,以便处理各种 DRM 方案的版权管理和解密操作。

Android 平台上的数字版权管理架构

图 3. Android 平台上的数字版权管理架构