摘要:随着数据隐私变得越来越重要,谷歌一直在试图增强移动操作系统的功能,用以保护Android移动设备和端点的所有数据。Android 9.0 P(Pie)预计在8月发布,其网络通信将默认为TLS。为了防止APP连接失败,Android移动应用程序开发人员将需要更新其后端服务,以支持HTTPS或实现Android网络安全配置功能。 

前言

随着数据隐私变得越来越重要,谷歌一直在试图增强移动操作系统的功能,用以保护Android移动设备和端点的所有数据。Android 9.0 P(Pie)预计在8月发布,其网络通信将默认为TLS。为了防止APP连接失败,Android移动应用程序开发人员将需要更新其后端服务,以支持HTTPS或实现Android网络安全配置功能。

当Android 6.0 Marshmallow发布时,谷歌提出了把android:usesCleartextTraffic作为防止意外使用明文通信的手段,Android 7.0 Nougat通过引入Android网络安全配置特性来扩展这个属性,这使得开发人员进一步规范了安全通信。Android的网络安全配置被称为Network Security Configuration,它是开发人员为Android应用程序定制的一个XML文件。

你们中的一些人可能认为这听起来很熟悉,因为iOS也使用类似的客户端检查配置,就是我们所说的App Transport Security。虽然与NSAppTranportSecurity相比,Network Security Configuration所提供的保护与其有很多相似之处。但它们在各自的平台上采取了截然不同的方法来实现网络安全。在这里不做赘述,让我们来看看在Android移动应用程序中使用Network Security Configuration的几个好处,并了解如何将其投入到实现该功能的最佳实践中。

实施优点

1.防止回归到明文通信

一条铁则:安全性乃重中之重。Android Network Security Configuration功能提供了一个简单的层,用来保护应用程序在未加密的明文中意外传输的敏感数据。

如果你不知道“未加密的通信”意味着什么,那么让我们设想这样一个情景,假设你的办公室有一个规定——必须通过UPS来运送所有货物。一个新的实习生加入了办公室,负责运送货物到全国各地的办公室。但是实习生忘记了这项规定,并通过一个未知的、不太昂贵的服务来承包了所有货物的转运。Android Network Security Configuration就像是一个发送和接收的管理器,它检查所有入站和出站的货物,并在设备进入未经审核的交付系统之前停止装运,它可以用来防止意外地使用不可信的、未加密的连接。

Android 9最大的变化之一是在默认情况下,cleartextTrafficPermitted允许被设置为false。这意味着,如果你没有看到这个标志被明确设置为false,并且应用程序的API级别低于28,则该标志将被判断为true。

在Network Security Config中使用的cleartextTrafficPermitted标志的另一个能力,是在特定域和子域上执行真正的设置:

Network Security ConfigurationShell

            insecure.example.com        

2.为安全连接设置可信证书颁发机构

可信证书机构(Trusted Certificate Authorities,CA)可以充当信任中介。在前文所说的故事中,办公室安全策略是将货物托付给UPS,但是也可以把业务交给其他物流公司,比如说FedEx、DHL等。归根结底,你信任谁来安全地发送应用程序数据并防止中间人攻击(MITM)呢?而现在,开发人员可以使用Android Network Security Configuration功能来指定他们信任哪些CA来颁发证书,并确保通信的安全。

首先,Android Network Security Configuration给开发者提供了一些可供选择的CA,默认情况下,Android 7 +(Nougat, Oreo and Pie)所使用的信任锚将是预先安装的系统CA证书,称为“system(系统)”:

Trust Anchors: Android 7+Shell

                                    

在Android 6 (Marshmallow)及其以下的,默认的信任锚还将包括用户安装的证书,称为“user(用户)”:

Trust Anchors: Android 6 and belowShell

                                                

最后,可以设置自定义信任锚:

Trust Anchors: CustomShell

                                    

3.实施证书锁定

实施证书锁定又增加了一层安全性。让我们重新回顾一下货物运输的故事,如果可信的CA是诸如UPS、FedEx等的公司,那么证书锁定类似于指定你所信任公司的哪项服务来运送你的货物。Android Network Security Configuration特征可以用来限制仅由可信CA颁发的特定证书用以通信。

我们讨论了在以前所研究过的实现证书锁定的方法,在下面的示例中,我们可以针对特定域和子域,将引脚设置为备份,并设置有效日期。

Certificate Pinning with Network Security ConfigShell

            example.com                    7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=                        fwza0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM1oE=            

4.调试应用程序网络连接

Android Network Security Configuration中提供的另一个选项是调试重写。此特性允许你在Network Security Config中设置只有当android:debuggable为true时才可用。例如,你可以使用自定义CA,为质量保证/预生产环境配置自定义信任锚,这会简化封闭环境测试,因为应用商城不接受标记为可调试的应用程序。

Debug OverridesShell

                                    

实施建议

你已经了解了部署Network Security Configuration的一些好处,现在让我们来介绍一些实现此文件的最佳实践。

首先,检查应用程序清单,看看它是否有这个特性。查找android:networkSecurityConfig,类似于这样:

Sample Manifest with Network Security ConfigShell

            ...    

一旦找到了Network Security Configuration文件,就到了检查如何允许明文通信的时候了。

下面的示例代码是一个反例:

Bad Example: cleartext Permissions with Network Security ConfigShell

            example.com        cdn.example2.com        

虽然这确保了所有到example.com和cdn.example2.com的通信都是通过HTTPS发送的,但是发送给其他域的所有通信都默认可以是明文,这完全违背了Network Security Configuration功能的预期目的——加强保护通过Android设备传输的所有数据的隐私。

如果你的移动应用程序必须以明文发送数据,那么这样做只会加密某些域的通信。此外,还必须仔细检查端点,明确允许HTTP检查敏感数据和其他API相关问题:

Recommended Implementation of cleartext PermissionsShell

            insecure.example.com        insecure.cdn.example.com        

另一个要考虑的是关于cleartextTrafficPermitted标志,它在Android 8及更低版本的默认值为true,因此,在所有应用程序的Network Security Configuration中,要明确将其设置为false。

让我们看看下面的另一个反例:

Bad Example: Default Implementation of Trust Anchors for Android 6 and belowShell

                                                

在此示例中,我们看到应用程序正在接受其信任锚中的用户证书,这意味着应用程序将以与系统预置证书相同的方式,来信任用户安装的证书。配置应用程序使用的信任锚时,最好仅限制对系统证书的信任,并在必要时限制应用程序内构建的自定义CA,这有助于防止攻击者能够在设备上安装证书来进行中间人攻击(MITM)。作为Android 7中引入的保护措施的一部分,默认情况下,用户安装的证书不像预先安装的证书那样受信任。如前所述, Android 6及更低版本默认接受用户证书,因此,在必要时明确选择“system(系统)”和/或自定义CA并在所有应用中排除“user(用户)”非常重要。

Recommended Implementation of Trust Anchors with Custom CA (When Necessary)Shell

                                                

让我们再来看一个锁定反例:

Bad Example: Certificate Pinning with Network Security ConfigShell

            example.com                    7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=            

上面的例子揭示了应用程序中的两个潜在问题。首先,没有设置pin-set的有效期,第二,没有备份引脚——一个聪明的策略是要设置证书有效期并有多个备份引脚的,旋转四个引脚并不是闻所未闻。如果没有明确设置pin的有效期,则应用程序在到期后将无法连接,但是如果你设置了一个有效期,当pin协议失效时,应用程序不是无法连接,而是将故障转移到设备上的系统CA。

Recommended Implementation of Certificate Pinning with Network Security ConfigShell

            example.com                    7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=                        fwza0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM1oE=            

最后,让我们来谈谈Network Security Config调试的重写。

Recommended Implementation of Debug Overrides with Network Security ConfigShell

                                    

虽然调试功能可以帮助消除应用程序中的调试网络代码,但请务必删除应用程序中的任何调试CA。作为一个最佳操作,应避免在你的应用程序中留下任何不必要的信息,因为这可能会带来安全风险,特别是当内部CA证书包含在应用程序的最终产品构建中时。

小结

从安全分析员的角度来看,知道如何在网络安全配置中读取和发现问题是很重要的。正如我们所看到的,在安装之前,我们可以在应用程序中找到一些潜在的问题,但是请记住,这些发现本身并不能证明你的应用程序的网络连接是安全的。

首先,你需要确定你的应用程序是否正在执行主机名验证,因为Network Security Configuration的保护不能解决此类问题。然后,确保你的第三方库符合Network Security Configuration,如果不这样做的话,可能会导致你的应用程序出现问题。此外,Network Security Configuration不受较低级别的网络连接(如websockets)的支持。最后你要记住,移动中的网络相关问题只是移动测试总体范围的一小部分。

总体而言,Android Network Security Configuration为Android提供了许多简单的网络安全功能,如果你的应用程序目前没有利用Network Security Configuration,你必须在未来一年中使用它。

与Android P的发布同步,谷歌已经开始在应用程序商城中实施目标API级别,以减少移动操作系统碎片,并将用户推向当前版本。虽然谷歌计划逐步增加每一个新版本的数量,但是目前的需求仍是26,不过到明年这个时候,API级别30(Android Q)很可能会被淘汰,这意味着如果你的应用程序使用HTTP,则必须在Network Security Configuration文件中声明,因为那时的强制目标API级别将为28。

更多相关文章

  1. Android应用程序注冊广播接收器(registerReceiver)的过程分析
  2. Android编程之manifest上遇到的错误
  3. Android系统的架构
  4. 【Android高级】Android系统以及Activity启动讲解
  5. 让Qt应用程序跑在Android上
  6. Android(安卓)NDK简介
  7. 8 个最优秀的 Android(安卓)Studio 插件
  8. Android(安卓)使用【AIDL】调用外部服务
  9. android应用开发入门

随机推荐

  1. Nodejs 源码阅读指南
  2. kafka数据定时导入hive便于后续做数据清
  3. 【DB笔试面试663】在Oracle中,死锁的产生
  4. 【DB笔试面试661】在Oracle中,在新建或重
  5. js bridge 实现原理
  6. Shell脚本中的while getopts用法小结
  7. 全文检索技术ElasticSearch使用
  8. 【js效果】倒计时
  9. 【DB笔试面试672】在Oracle中,errorstack
  10. 【DB笔试面试660】在Oracle中,在编译存储