Group of Software Security In Progress

GoSSIP @ LoCCS.Shanghai Jiao Tong University

Up-To-Crash: Evaluating Third-Party Library Updatability on Android

作者:Jie Huang, Nataniel Borges, Sven Bugiel, Michael Backes

单位:CISPA Helmholtz Center for Information Security

出处:EuroS&P’19

原文:https://publications.cispa.saarland/2885/1/up2crash-euros%26p-cr.pdf


Abstract

存在漏洞和缺陷的第三方库不仅增大了App的受攻击面,同时也将用户的隐私暴露在风险之中。App开发人员必须将App中集成的第三方库保持更新至最新版本,以防范这样的风险。最新的研究表明,Android App中普遍存在有过时的第三方库,一种可行的解决方案是在不需要App开发人员帮助的前提下直接替换过时的第三方库至更高版本。但是,所有的这些结论都是基于静态App分析得到的,其只能提供一个粗略的估计。

文章通过分析App的运行时行为对第三方库的可更新性进行了重新评估。作者实现了一个直接替换第三方库至更高版本的更新方案,并对3,000个集成有流行第三方库(三个第三方库的78个版本)的真实App进行了动态测试,以验证此更新方案的可行性。文章还使用了探测增强的动态测试来监控15个App在第三方库更新前后的运行时行为,以深入研究第三方库的可更新性。测试结果表明,已有研究中提出的第三方库的可更新率在实际条件下被高估了1.57至2.06倍,而阻碍直接替换第三方库至更高版本的潜在问题也是错综复杂的,例如弃用的方法,改变的数据结构,以及第三方库之间纠缠的依赖关系。

1. Introduction

应用程序开发人员通常会将第三方库集成进应用程序中以加速其开发过程。已有研究表明,Android App中普遍集成有存在漏洞的第三方库,大约70%的免费App中存在的漏洞都来源于其中集成的第三方库。针对这些漏洞最直接的对策便是更新:第三方库开发人员发布修复的版本,App开发人员将App中集成的第三方库更新至修复的版本。然而,大多数App开发人员倾向于在App中保留过时的第三方库,以避免由于更新第三方库至更高版本而带来的兼容性问题。

最新的研究表明, 在完全基于第三方库各个版本之间API兼容性的前提下,85.6%的第三方库可以被直接替换至更高版本,48.2%的第三方库甚至可以被直接替换至最新版本。但是,所有的这些第三方库的可更新率都是来源于静态App分析的,其只能从语法的角度上来提供一个第三方库可更新率的上界估计。针对这一现状,作者尝试在本文中回答以下三个待研究的问题:

  1. 第三方库的可更新性在实际条件下究竟是怎样的?
  2. 直接替换第三方库至更高版本是否会带来兼容性问题?
  3. 导致这些兼容性问题的主要原因又是什么?

为了回答这些问题,本文研究了直接替换第三方库至更高版本前后App的运行时行为,包含以下两个步骤:1)实现一个第三方库的自动化更新方案;2)分析第三方库更新前后App的运行时行为。本文的主要贡献如下:

  1. 基于API兼容性的第三方库更新框架;
  2. App运行时行为分析;
  3. 针对直接替换第三方库至更高版本而带来的兼容性问题的深入研究。

2. Android Software Updating and Testing

Android软件更新的官方来源可以被分为四类:App开发人员,Android开源项目(AOSP),上游Linux内核,以及SoC芯片供应商。设备制造商是Android平台底层软件更新链中的瓶颈,而App开发人员则是第三方库更新链中的瓶颈。

20190715142426

Google Play通过其应用程序安全性改进计划拒绝任何集成有存在已知安全漏洞的第三方库的App上架,以强制开发人员更新其App中集成的第三方库。但是,此机制只适用于很少一部分的第三方库,例如Apache Cordova,其余更多的存在漏洞的第三方库并不会被该机制所审查。

除了通过前述的标准更新链来完成更新之外,Android软件还可以通过第三方修复技术与应用程序自主热修复技术来进行更新。文章依赖于Android测试输入生成技术来评估App的运行时行为,并识别由于更新第三方库至更高版本而带来的兼容性问题。Android测试输入生成技术所依赖的底层探测引擎可以分为以下三类:随机的探测引擎,基于模型的探测引擎,以及系统的探测引擎。

3. Motivation

基于API兼容性的第三方库可更新性:

20190715151304

自动化第三方库更新框架:

为了尽可能的消除不必要的干扰,同时可靠的识别由于更新第三方库至更高版本而带来的兼容性问题,文章借鉴了已有框架中通过类加载器定制(classloader customization)来选择加载代码的思想,设计并实现了一个动态直接替换第三方库至更高版本的更新框架,以支持第三方库的自动化更新。

自动化第三方库更新测试:

文章使用自动化用户界面(UI)测试,通过在App上执行一系列的UI操作,并比较直接替换第三方库至更高版本前后App的运行时行为,以识别由于更新第三方库至更高版本而带来的兼容性问题。

4. Two-Stage Updating Experiment

A. Stage-1: Automated Library Update Framework

为了在不修改App代码的前提下完成第三方库的自动化更新,本文设计并实现了一个动态更新框架。此框架利用了Android类加载器层次结构的类域隔离与代码动态加载的特性,从而使得在App的加载过程中过时的第三方库能够被定制的类加载器自动化的替换至更高版本来进行加载,并且在此过程中不需要额外修改任何的App代码。此框架由以下三个模块组成:更新运行时环境(Update Execution Environment),更新处理程序(Update Handler),以及第三方库中心(LibCenter)。

20190715163718

更新运行时环境:

为了避免由于修改App代码而导致的App运行时错误,本框架设计并实现了一个作为原生Android系统扩展的更新运行时环境,从而在App初始化之前选择加载更高版本的第三方库来替换过时版本。此环境由以下两个关键组件构成:1)更新状态管理组件(Update Status Management Component);2)App入口分散组件(App Entrance Diversification Component)。

更新状态管理组件管理每个App的更新状态,并允许用户控制App中加载的第三方库的版本。App入口分散组件是实际上第三方库更新的部署场所,其负责将更高版本的第三方库加载进应用程序中。

20190715170356

更新处理程序:

更新处理程序是连接App与第三方库更新的桥梁,其负责激活App中集成的第三方库的更新。此程序主要由以下三个关键组件构成:1)更新类加载器链(Update ClassLoader Chain);2)更新资源加载器(Update Resources Loader);3)更新Application类(Update Application)。

更新类加载器链是一个特别用于动态第三方库更新的定制的类加载器链。更新资源加载器负责将更高版本的第三方库的资源集成进App中。更新Application类是一个定制的Application类,其负责确保更高版本的第三方库在任何App代码接管之前被激活。

20190715170655

第三方库中心:

第三方库中心是一个集中式的第三方库的资源库,所有预编译的第三方库包以及元数据都存储于此。作者使用LibScout工具作为第三方库中心的一部分,收集了所有安装的App的元数据,包括App中集成的第三方库与基于API兼容性的第三方库可更新性。

B. Stage-2: Automated User Interface Tests

为了确保此实验的全面性,作者首先进行了大规模的动态测试,以验证文章提出的更新框架的可行性,并识别在目标App中由于直接替换第三方库至更高版本而带来的直接运行时错误,例如App崩溃。随后,作者进行了加强的动态测试,以探测更多的App功能,并触发更多的由于更新第三方库至更高版本而带来的隐藏运行时错误,例如改变的第三方库行为。

目标第三方库与App:

文章从不同的第三方库分类中选择了包含有总共78个版本的三个第三方库作为目标第三方库:OkHttp(开发工具),Facebook SDK(社交SDK),以及Facebook Audience(广告网络)。

作者从Google Play上爬取了332,432个免费App,并使用LibScout工具从中选出了3,000个集成有目标第三方库并调用了各个第三方库中常用API集的App来进行动态测试。

Monkey测试:

在此大规模评估测试中,作者尝试将每个第三方库更新至API兼容的最新版本,并使用Monkey工具运行这些App,以完成500次随机事件的探测。

考虑到某些App可能会由于存在设计缺陷等原因而导致App运行时出错,作者首先在原始App上进行Monkey测试,只有在此测试成功执行且没有出现任何错误的前提下,这些App才能被考虑进行第三方库更新。

20190716004731

DroidMate测试:

在此测试中,作者从Monkey测试随机选取了15个App,并对这些App在更新前后的运行时行为进行了比较分析。作者将运行时执行的源代码块视为App的功能,将更新前后运行时执行的代码块的变化视为行为改变。为了探测更深层次的App功能,同时获取更加精确的测试结果,作者为开源的DroidMate工具开发了一款插件,以绕过Monkey测试中存在的限制,例如缺少登录或注册信息。

作者使用DroidMate工具运行每个App直到获取到10条到达目标第三方库的执行路径为止,每次执行包含有500次合法UI元素的事件。作者开发的DroidMate工具的插件在登录和注册界面上执行预定义的操作,并使用DroidMate工具标准的偏差随机的方式来探测剩余的界面。

20190716011213

5. Root Cause Analysis

A. Findings from Monkey Testing

作者只关注与第三方库更新有明显联系的App运行时错误,即只考虑在异常信息中包含有与第三方库特定相关的关键词的App运行时错误。

20190716011247

AbstractMethodError:

当一个抽象方法被调用但是目标类的定义与当前执行的方法不兼容时,该异常将会被触发。LibScout使用根包匹配的方式来检测第三方库的调用。由于抽象方法的实现通常以App包的前缀来命名,LibScout并不会把抽象方法的调用视为第三方库的调用。

ClassNotFoundException:

当类加载器链中的一个类加载器无法根据类名来加载目标类时,该异常将会被触发。LibScout使用根包匹配的方式来检测第三方库的调用。兄弟第三方库的方法都是以相同的前缀来命名的,因此LibScout并不会把兄弟第三方库之间的调用视为第三方库的调用。

FacebookException:

该异常是一个Facebook定制的异常,当Facebook SDK中发生了一个内部错误时,该异常将会被触发。由于AndroidManifest.xml的改变并不包括在测试的设置中,因此所有原始第三方库SDK的配置都将被保留在App中。

20190716011419

B. DroidMate Finding

“bio”域的使用与更高版本Facebook SDK中使用的Graph API不兼容,从而导致App的登录失败。由于“bio”域只是字符串参数的一个部分,因此LibScout无法检测此第三方库调用的API兼容性。

20190716015901

C. Case Study

弃用的方法:

20190716015955

20190716020032

改变的清单文件:

20190716021245

D. Library Updatability Re-Estimation

20190716021335