3.安全设计和安全编码的基本知识

虽然本指南是有关 Android 应用程序开发的一系列安全建议,但本章将介绍有关 Android 智能手机和平板电脑通用安全设计和安全编码的基本知识。由于我们将在后面的章节中提到安全设计和编码概念,我们建议您首先熟悉本章中的内容。

3.1.Android 应用程序安全

在审视有关系统或应用程序的安全问题时,有一种普遍接受的思维方式。首先,我们需要知晓要保护的对象。我们将这些对象称为资产。接下来,我们希望了解可能发生的资产攻击。我们称之为威胁。最后,我们会审视并实施措施,以保护资产免受各种威胁的影响。我们将这些措施称为对策。

这里的对策是指安全设计和安全编码,在第 4 章之后,我们将讨论这些主题。在本章节中,我们将重点介绍资产和威胁。

3.1.1.资产:保护对象

系统或应用程序中有两种类型的保护对象:信息和功能。我们将其称为信息资产和功能资产。信息资产是指只有具有权限的人员才能引用或更改的信息类型。这是一种任何没有该权限的人都不能引用或更改的信息类型。功能资产指的是只能由具有权限的人员使用的功能,没有权限则无法使用。

下面,我们将介绍 Android 智能手机和平板电脑中存在的信息资产和功能资产的类型。我们希望您在开发使用 Android 应用程序或 Android 智能手机/平板电脑的系统时,将以下内容作为参考,谨慎对待与资产相关的问题。为了简单起见,我们将 Android 智能手机/平板电脑统称为 Android 智能手机。

3.1.1.1.Android 智能手机的信息资产

表 3.1.1表 3.1.2 显示了 Android 智能手机中包含的信息示例。必须采取适当的保护措施,因为此信息等同于个人信息、机密信息或兼具这两种性质的信息。

表 3.1.1 由 Android 智能手机管理的信息示例
信息 备注
电话号码 智能手机本机电话号码
通话记录 呼入和呼出电话的时间和日期以及电话号码
IMEI 智能手机的设备 ID
IMSI 用户 ID
传感器信息 GPS、地磁性、加速率等
各种设置信息 Wi-Fi 设置值,等等…
帐户信息 各种帐户信息、身份验证信息等
媒体数据 图片、视频、音乐、录音等…
 
表 3.1.2 应用程序管理的信息示例
信息 备注
联系人 常用联系人
电子邮件地址 用户的电子邮件地址
Web 书签 书签
Web 浏览历史记录 浏览历史记录
日历 计划、待办事项清单、活动等
Facebook SNS 内容等
Twitter SNS 内容等
 

表 3.1.1 中显示的信息类型主要是存储在 Android 智能手机本身或 SD 卡上的信息类型。类似地,表 3.1.2 中显示的是主要由应用程序管理的信息类型。但不同的是,表 3.1.2 中显示的信息类型与设备上安装的应用程序数量成比例增长。

表 3.1.3 是一个联系人条目实例中包含的信息量。此处所示信息并非智能手机用户的信息,而是智能手机用户的朋友的信息。换言之,我们必须知道智能手机不仅包含有关用户的信息,还包含其他人的信息。

表 3.1.3 一个联系人条目中包含的信息示例
信息 内容
电话号码 家庭电话号码、移动电话号码、传真、彩信等
电子邮件地址 家庭电子邮件、工作电子邮件、移动电话电子邮件等
照片 缩略图、大图像等
IM 地址 AIM、MSN、Yahoo、Skype、QQ、Google Talk、ICQ、Jabber、NetMeeting 等
昵称 首字母缩写词、首字母、婚前姓、昵称等
地址 国家/地区、邮政编码、地区、区域、城镇、街道名称等
组成员资格 收藏夹、家人、朋友、同事等
网站 博客、个人资料站点、主页、FTP 服务器、家庭、办公室等
活动 生日、周年纪念日等
关系 配偶、子女、父亲、母亲、经理、助理、同居伴侣、伴侣等
SIP 地址 家庭、工作等

到目前为止,我们主要关注有关智能手机用户的信息,但是,应用程序也具有其他重要信息。图 3.1.1 显示了应用程序内部信息的典型视图,这些信息划分为程序部分和数据部分。程序部分主要包含有关应用程序开发人员的信息,数据部分主要与用户信息相关。由于应用程序开发人员可能不希望用户访问某些信息,因此有必要提供保护措施以禁止用户引用或更改此类信息。

_images/image25.png

图 3.1.1 应用程序中包含的信息

创建 Android 应用程序时,应用程序对其自身管理的信息采取适当的保护措施非常重要,如图 3.1.1 中所示。但是,对于 Android 智能手机本身包含的信息以及其他应用程序中获得的信息(如 表 3.1.1表 3.1.2表 3.1.3 中所示)采取强有力的安全措施同样重要。

3.1.1.2.Android 智能手机的功能资产

表 3.1.4 显示了 Android 操作系统为应用程序提供的功能示例。当恶意软件等利用这些功能时,可能会给用户带来意外费用或隐私泄露等形式的损害。因此,应制定与扩展到信息资产的措施相同的适当保护对策。

表 3.1.4 Android 操作系统为应用程序提供的功能示例
功能 功能
发送和接收 SMS 消息 摄像头
通话 音量
网络通信 读取移动电话的联系人列表和状态
GPS SD 卡
蓝牙通信 更改系统设置
NFC 通信 读取日志数据
互联网通信 (SIP) 获取正在运行的应用程序的信息

除了 Android 操作系统为应用程序提供的功能,Android 应用程序的应用程序间通信组件也作为功能资产的一部分包含在内。Android 应用程序可允许其他应用程序通过访问其内部组件来利用功能。我们称之为应用程序间通信。这是一项方便的功能,但也存在这样的情况:由于开发人员对安全编码缺乏了解,本应仅在特定应用程序内部使用的功能的访问权限被错误地授予给其他应用程序。应用程序提供的功能可能被驻留在设备本地的恶意软件利用。因此,有必要采取适当的保护措施,仅允许合法应用程序访问这些功能。

3.1.2.威胁:威胁资产的攻击

在上一章节中,我们讨论了 Android 智能手机的资产。在本章中,我们将介绍可能威胁资产的攻击。简而言之,对资产的威胁是指原本不应具有相应权限的第三方访问、更改、删除或创建了信息资产或非法使用了功能资产。直接或间接攻击此类资产的行为称为“威胁”。此外,实施这些行为的恶意人员或应用程序也称为威胁的来源。恶意攻击者和恶意软件是威胁的来源,但不是威胁本身。我们对资产、威胁、威胁源、漏洞和损害的定义之间的关系显示在下面的图 3.1.2 中。

_images/image26.png

图 3.1.2 资产、威胁、威胁源、漏洞和损害之间的关系

图 3.1.3 显示了 Android 应用程序运行所在的典型环境。下面我们会以此图为基础,展开讨论有关 Android 应用程序面临的威胁类型,为此,我们要首先学习如何查看这张图。

_images/image27.png

图 3.1.3 运行 Android 应用程序的 Android 典型环境

上图左侧展示的是智能手机,右侧展示的是服务器。智能手机和服务器在 3G/4G/Wi-Fi 网络中通过互联网进行通信。虽然智能手机中存在多个应用程序,但我们仅在图中显示一个应用程序,以便清楚地解释威胁。基于智能手机的应用程序主要处理用户信息,但基于服务器的 Web 服务共同管理其所有用户的信息。因此,服务器安全的重要性照常没有改变。我们不会讨论与服务器安全有关的问题,因为它不在本指南的讨论范围之内。

我们将使用下图描述 Android 应用程序面临的威胁类型。

3.1.2.1.基于网络的第三方

_images/image28.png

图 3.1.4 基于网络的恶意第三方攻击应用程序

通常,智能手机应用程序管理服务器上的用户信息,因此信息资产将在连接它们的网络之间移动。如图 3.1.4 所示,基于网络的恶意第三方可能会在此通信过程中访问(嗅探)任何信息,或尝试更改信息(数据操纵)。中间的恶意攻击者(也称为“中间人”)也可能伪装成真实的服务器,借此攻击应用程序。不用说,基于网络的恶意第三方通常也会尝试攻击服务器。

3.1.2.2.用户安装的恶意软件带来的威胁

_images/image29.png

图 3.1.5 用户安装的恶意软件攻击应用程序

智能手机的最大卖点在于它能通过市场获得大量应用程序,以便扩展其功能。用户能够自由安装许多应用程序的缺点在于,他们有时会不小心安装恶意软件。如图 3.1.5 所示,恶意软件可能利用应用程序间的通信功能或应用程序中的漏洞来访问信息或功能资产。

3.1.2.3.利用应用程序中漏洞的恶意文件的威胁

_images/image30.png

图 3.1.6 利用应用程序中漏洞的恶意文件进行的攻击

互联网上广泛提供了音乐、图像、视频和文档等各种类型的文件,用户通常会将许多文件下载到其 SD 卡,以便在智能手机上使用它们。此外,下载通过电子邮件发送的附件的做法也很常见。这些文件稍后可由查看或编辑应用程序打开。

如果处理这些文件的应用程序的功能中存在任何漏洞,攻击者可以使用恶意文件来利用此漏洞,并获得对应用程序的信息或功能资产的访问权限。特别是,在处理具有复杂数据结构的文件格式时,通常会存在漏洞。当以这种方式利用应用程序时,攻击者可以实现许多不同的目标。

图 3.1.6 所示,攻击文件在被存在漏洞的应用程序打开之前一直处于休眠状态。一旦打开,它就会利用应用程序的漏洞,开始实施严重破坏。我们将此攻击方法称为“被动攻击”,与主动攻击形成对比。

3.1.2.4.恶意智能手机用户的威胁

_images/image31.png

图 3.1.7 恶意智能手机用户的攻击

关于 Android 智能手机的应用程序开发,相关环境以及有助于开发和分析应用程序的功能均公开提供给普通用户。在提供的功能中,任何人都可以访问有用的 ADB 调试功能,而无需注册,也不需要经过筛查。此功能允许 Android 智能手机用户轻松执行操作系统或应用程序分析。

图 3.1.7 所示,具有恶意意图的智能手机用户可以通过利用 ADB 的调试功能来分析应用程序,并尝试访问应用程序的信息或功能资产。如果应用程序中包含的实际资产属于用户,则不会产生问题,但如果资产属于用户以外的其他人,如应用程序开发人员,则会造成问题。因此,我们需要注意,合法的智能手机用户可以在应用程序中恶意地利用资产。

3.1.2.5.智能手机附近的第三方威胁

_images/image32.png

图 3.1.8 智能手机附近恶意第三方的攻击

考虑到大多数智能手机都有各种近场通信机制,如 NFC、蓝牙和 Wi-Fi,我们一定不能忘记,攻击可能来自于智能手机物理位置附近的恶意攻击者。在用户输入密码时,攻击者可能会偷窥到密码。或者,如图 3.1.8 所示,攻击者可能采取更高级的手法,远程攻击应用程序的蓝牙功能。此外还有一种威胁形式,即恶意人员可能会偷窃智能手机,导致数据泄露甚至破坏智能手机,从而导致重要信息丢失。开发人员需要在设计阶段的早期考虑这些风险。

3.1.2.6.威胁总结

_images/image33.png

图 3.1.9 对智能手机应用程序的各种攻击的总结

图 3.1.9 总结了前面章节中介绍的主要威胁类型。智能手机面对着多种多样的威胁,上图并未包含所有威胁。通过我们的日常信息收集,我们需要传播有关 Android 应用程序面临的各种威胁的意识,并在应用程序的安全设计和编码过程中关注这些威胁。以下由日本智能手机安全协会 (JSSEC) 制作的文献包含有关智能手机安全威胁的其他有用信息。

3.1.3.资产分类和保护对策

正如前面章节所讨论的,Android 智能手机面临着多种多样的威胁。由于开发所需的时间和技术限制,保护应用程序中的每项资产免受此类威胁可能会非常困难。因此,Android 应用程序开发人员应审视适用于其资产的可行对策。应根据开发人员的判断标准,按照优先级完成此项任务。这是一个主观问题,以资产的重要性和可接受的损失程度为依据。

为了帮助确定每项资产的保护对策,我们将对其进行分类,并针对每组给出保护对策级别的规定。这可通过检查法律依据来实现,涉及到可能发生的任何损害的影响程度以及开发人员(或组织)的社会责任。事实可以证明,在决定如何处理每项资产以及各种对策类型的实施方法时,这些依据将成为判断标准。也正是由于它们将成为应用程序开发人员和组织确定如何处理资产和提供保护措施的标准,因此有必要根据应用程序开发人员(或组织)的情况指定分类方法和相关对策。

下面展示了本指南中采用的资产分类和保护对策级别以供参考:

表 3.1.5 资产分类和保护对策级别
资产分类 资产级别 保护对策的级别
[1]

资产造成的损失程度是致命性的,会给组织或个人的活动带来灾难性的损害。

也就是说,在这种级别的资产受损时,组织将无法继续正常开展业务。

针对突破 Android 操作系统安全模式的复杂攻击提供保护,防范 root 权限泄漏和篡改 APK 的 dex 部分的攻击。

确保安全性优先于用户体验等其他要素。

资产造成的损失程度对组织或个人的活动有重大影响。

也就是说,在这种级别的资产受损时,组织的利润水平将恶化,从而对其业务产生不利影响。

利用 Android 操作系统安全模式。它能在其适用范围内提供保护。

确保安全性优先于用户体验等其他要素。

资产造成的损失程度对组织或个人活动的影响有限。

也就是说,在这种级别的资产受损时,组织的利润水平将受到影响,但能够利用其他资源补偿其损失。

利用 Android 操作系统安全模式。它能在其适用范围内提供保护。

将安全对策与用户体验等其他元素进行比较。在这个级别上,非安全问题可能优先于安全问题。

指南中所述的资产分类和保护对策是在 root 权限未泄漏的安全 Android 设备的前提下提出的。此外,它基于利用 Android 操作系统安全模式的安全措施。具体而言,我们假设在正常运行的 Android 操作系统安全模式的基础上,利用 Android 操作系统安全模式来设计保护对策,保护那些被归类为低于或等于“中”级别的资产。

[1]我们还相信有必要保护高级资产免受由于违反 Android 操作系统安全模式而导致的攻击。此类攻击包括 root 权限泄漏,以及分析或篡改 APK 二进制文件的攻击。为了保护这些类型的资产,我们需要结合使用加密、混淆、硬件支持和服务器支持等多种方法来设计精密的防御对策,以防范此类威胁。由于无法通过三言两语在本指南中列举有关这些防御措施的知识,并且合理的防御措施设计因个别情况而异,我们认为这些内容超出了本指南的讨论范围。如果您的设备需要防范复杂的攻击,包括由于分析或篡改 APK 文件而导致的 root 权限泄露或攻击,我们建议您咨询精通 Android 防篡改设计的安全专家。

3.1.4.敏感信息

从现在起,本指南中将使用术语“敏感信息”而不是信息资产。正如上一节中所述,我们必须确定应用程序处理的每项信息资产的资产级别和保护对策的级别。

3.2.谨慎且安全地处理输入数据

验证输入数据是最简单但最有效的安全编码方法。无论是由外部来源直接输入还是间接输入,输入到应用程序中的所有数据都需要进行合理的验证。为了说明输入数据验证的最佳做法,下面是一个接收到来自 Intent 的数据的程序中使用的活动示例。

活动可能会收到来自 Intent、被攻击者篡改的数据。通过以超出程序员预期的的格式或值发送数据,攻击者即可引起应用程序功能失灵,从而导致某种安全事件。我们一定要牢记,用户也可能成为攻击者。

Intent 是按操作、数据和附加条件进行配置的,在接受攻击者可以控制的所有形式的数据时,我们必须小心谨慎。如果代码处理的数据来自不受信任的来源,我们始终需要验证以下项目。

(a) 接收到的数据是否与程序员预期的格式匹配,该值是否在预期范围内?

(b) 即使您已收到预期的格式和值,您是否可以保证处理该数据的代码不会出现意外行为?

下面是一个简单示例,其中 HTML 是从指定 URL 中的远程网页获取的,代码显示在 TextView 中。但其中存在 bug。

在 TextView 中显示远程网页 HTML 的示例代码

TextView tv = (TextView) findViewById(R.id.textview);
InputStreamReader isr = null;
char[] text = new char[1024];
int read;
try {
    String urlstr = getIntent().getStringExtra("WEBPAGE_URL");
    URL url = new URL(urlstr);
    isr = new InputStreamReader(url.openConnection().getInputStream());
    while ((read=isr.read(text)) != -1) {
        tv.append(new String(text, 0, read));
    }
} catch (MalformedURLException e) { //...

从 (a) 点来看,“urlstr 是正确的 URL”,新 URL() 未引发 MalformedURLException 异常的事实证明了这一点。但是,这还不够。此外,当“file://...”格式的 URL 由 urlstr 指定时,将打开内部文件系统的文件,并在 TextView 而非远程网页中显示此文件。这无法满足 (b) 点,因为它不能保证实现程序员预期的行为。

下一个示例显示了用于修复安全漏洞的修正。通过 (a) 点,通过检查“urlstr 是合法的 URL,协议限制为 http 或 https”,来验证输入数据。因此,即使根据 (b) 点,也可以通过 url.openConnection().getInputStream() 保证获取由 Internet 路由的 InputStream。

下面是修正后的示例代码,它在 TextView 中显示基于 Internet 的网页 HTML

TextView tv = (TextView) findViewById(R.id.textview);
InputStreamReader isr = null;
char[] text = new char[1024];
int read;
try {
    String urlstr = getIntent().getStringExtra("WEBPAGE_URL");
    URL url = new URL(urlstr);
    String prot = url.getProtocol();
    if (!"http".equals(prot) && !"https".equals(prot)) {
        throw new MalformedURLException("invalid protocol");
    }
    isr = new InputStreamReader(url.openConnection().getInputStream());
    while ((read=isr.read(text)) != -1) {
        tv.append(new String(text, 0, read));
    }
} catch (MalformedURLException e) { //...

验证输入数据的安全性称为“输入验证”,它是一种基本的安全编码方法。根据“输入验证”这个词的意义可以推测,(a) 点往往得到重视,而 (b) 点往往会被忽视。请务必牢记,损失并非发生在数据进入程序之时,而是发生在程序以错误方式使用数据之时。我们希望您能抽些时间参考下面列出的网址。