Android应用中SQL注入漏洞静态检测方法*
2018-08-15潘秋红崔展齐王林章
潘秋红,崔展齐,王林章,2,3+
1.南京大学 计算机科学与技术系,南京 210023
2.南京大学 计算机软件新技术国家重点实验室,南京 210023
3.江苏省软件新技术与产业化协同创新中心,南京 210023
4.北京信息科技大学 计算机学院,北京 100101
1 引言
SQL(structured query language)注入是攻击者由外部输入向程序中原有的数据库执行语句中插入恶意SQL语句片段,篡改SQL执行命令来操作数据库的安全漏洞。无论是对于Web应用还是移动应用,SQL注入都是一个严重的安全问题。攻击者可以利用SQL注入漏洞窃取用户敏感信息,恶意篡改数据库中的内容,提升权限等,引发严重后果。根据OWASP(Open Web Application Security Project)发布的Web应用十大安全威胁中,从2010年至2017年4月,注入类漏洞都高居榜首[1]。
SQL注入漏洞对软件安全产生了巨大威胁,对SQL注入的检测和防范是开发者在开发软件时必须考虑的一个重要因素。已经提出了很多方法用于检测Web应用中的SQL注入漏洞,主要可分为静态分析[2]、动态测试[3]两类。静态分析方法如符号执行技术,其将符号作为值赋给变量,对程序的路径进行模拟执行,精确分析程序的代码属性[2]。动态测试则要通过运行软件来得到程序的动态行为信息,包括分析软件的覆盖率、监控内存的状态、分析执行轨迹、提取程序不变式等[3]。同时,针对Web应用中的SQL注入漏洞已有很多工具得到了广泛应用,如HPFortify SCA[4]、Coverity[5]等。
近年来,随着无线通信技术和移动互联网迅猛发展,移动终端普及率快速提高。据CNNIC(China Internet Network Information Center)第39次《中国互联网络发展状况统计报告》[6],截至2016年12月,我国手机网民规模已达到6.95亿,台式电脑、笔记本的上网比例则持续下降,网民上网设备进一步向移动端集中。其中,据CNNIC《2015年中国手机网民网络安全状况报告》[7],使用Android操作系统的手机占67.4%。根据Veracode 2016年发布的软件安全状态报告,在Android应用存在的安全漏洞中,SQL注入漏洞位列第八[8]。然而,Coverity、FindBugs[9]等面向Web应用的通用软件质量及安全漏洞检测工具未关注移动应用的SQL注入特性,导致无法有效识别Android应用中的SQL注入漏洞。此外,用于检测SQL注入漏洞的方法未使用污点分析等技术,针对Android应用进行静态污点分析的工具,如Flow-Droid[10]等,不支持直接检测SQL注入漏洞,即使通过人工修改配置文件增加对SQL注入漏洞的描述,也只是分析SQL方法中的SQL参数是否被污染,没有考虑应用中是否对外部输入进行过合法性检查,导致误报率较高。
针对上述问题,本文提出了一种基于污点分析的Android应用SQL注入漏洞静态检测方法。首先,根据Android应用的字节码文件进行程序静态分析,并在其上定位SQL注入漏洞的SQL方法和SQL参数;然后,通过静态污点分析方法,检测SQL参数是否来自外部输入;最后,基于SQL注入的输入验证机制,通过识别应用中是否存在对污染的SQL参数进行过合法性检查,来判断是否存在SQL注入漏洞。
本文的贡献包括以下两点:
(1)针对Android应用,提出一种基于污点分析的SQL注入漏洞静态检测方法;
(2)基于所提出的方法实现了原型工具SQLInj,并设计了一组实验来验证所提出方法的有效性。
本文组织结构如下:第2章介绍SQL注入漏洞模型;第3章详细分析基于静态分析的Android应用SQL方法及参数定位;第4章介绍方法的原型工具实现和实验评估;第5章讨论与本文相关的研究工作;第6节总结了本文的工作,并对下一步的研究计划进行展望。
2 SQL注入漏洞模型
SQL注入漏洞是发生在使用数据库对数据进行管理的应用程序中的一种安全漏洞,其本质是攻击者通过表单等方式进行外部输入,在应用程序中预先定义好的数据库查询语句中插入恶意的SQL语句,篡改其含义来欺骗数据库服务器执行非授权的查询[11],通过这些操作获得数据库信息,非法读取、修改、添加、删除数据,私自添加账号,注入木马等其他病毒。
攻击者一般通过构造有特殊含义的SQL语句进行SQL注入攻击,攻击方式大致可以分为以下几类[12-13]:重言式与注释符攻击、非法/逻辑错误查询攻击、联合查询攻击、推断攻击、基于存储过程或函数攻击、复合查询攻击、编码替换攻击等。
对于每种SQL注入攻击方式,其注入的字符串中通常会包含不同的敏感字符,这些字符是SQL语言中定义的拥有特殊含义的字符,攻击者就是通过这些字符篡改原SQL指令。将各类SQL注入攻击方式可能采用的敏感字符进行了整理,如表1所示。
Table 1 SQL injection sensitive characters表1 SQL注入敏感字符
为了能够检测出Android应用中的SQL注入漏洞,首先需要对SQL注入漏洞进行建模和分析,然后在此基础上对程序进行静态分析,并在代码中定位SQL注入攻击的SQL方法和SQL参数,最后通过污点分析及判断合法性检查判定程序中是否存在SQL注入漏洞。
假设将由若干语句(statement)组成的Android应用程序(program)表示为P={s1,s2,…,sn},则可将SQL注入漏洞模型定义如下:
(1)SQL方法为语句集合SSQL⊆P中的元素,其中,对任意的语句si∈SSQL,si为SQL操作语句,SQL操作语句包括rawQuery、execSQL、query等与数据库访问相关的API调用。
(2)对于SQL方法si,变量集合Pari={pari,1,pari,2,…,pari,m}为si所使用的参数,其中,pari,j∈Pari即为si的SQL参数。
(3)对于任意的SQL参数pari,j∈Pari若其与P的外部输入相关,且在使用前未进行过合法性检查,则认为SQL方法si存在SQL注入漏洞。
以图1所示的代码片段为例,其功能为当USER表中存在用户输入的用户名且其密码也正确时允许其登录。首先,分析程序发现第5行为SQL方法android.database.sqlite.SQLiteDatabase.rawQuery;然后,分析该SQL方法rawQuery中的SQL参数为sql和null;最后,对SQL参数进行分析,其中,参数sql在第3行通过字符串username和password拼接而来,而username和password是应用登录界面用户输入的用户名和密码,因此SQl参数sql与外部输入有关,且在SQL方法rawQuery执行前,程序并没有对SQL参数sql进行合法性检查,因此,可以判断SQL方法raw-Query处存在SQL注入漏洞。若攻击者在用户名和密码处均输入“1’OR‘1’=‘1”,则会通过SQL方法rawQuery中的SQL参数sql,将外部输入传递到后台数据库中。此时执行的SQL查询语句的形式为:
SELECT*from USER WHERE USERNAME=‘1’OR‘1’=‘1’AND PASSWORD=‘1’OR‘1’=‘1’;
在这种情况下,该SQL查询语句的结果恒为真,将会成功利用SQL注入漏洞进行攻击,攻击者无需正确的用户名和密码即可直接登录。
Fig.1 Example of SQL injection图1 SQL注入示例
3 基于污点分析的Android应用SQL注入漏洞静态检测技术
针对缺少专用的Android应用SQL注入漏洞检测工具,而现有的通用检测工具用于检测Android应用SQL注入漏洞时精确度较低的问题,本文提出了一种静态检测Android应用中潜在SQL注入漏洞的方法。如图2所示,首先,通过静态分析处理程序的结构,获得程序的控制流图和数据流图,并在程序中定位SQL方法和SQL参数;然后,对程序进行静态污点分析,判断SQL方法中的参数是否来自外部输入;最后,对于使用了污点数据的SQL方法,要判断应用中是否对其中的SQL参数进行了合法性检查,若不存在合法性检查,则认为这一条SQL方法存在SQL注入漏洞。
Fig.2 Flowchart of static detection approach for SQL injection vulnerability inAndroid applications图2 Android应用中SQL注入漏洞静态检测方法流程图
3.1 基于静态分析的SQL方法及参数定位
为了能够对代码进行静态检测,需要对程序的结构进行静态分析,使用合适的数据结构来描述代码。为扩大方法的适用范围,静态分析的对象采用了Android应用的字节码文件而非源代码。首先对程序进行静态分析,通过控制流分析、数据流分析等技术剖析程序的结构;然后在程序中定位SQL注入漏洞模型中的SQL方法及相应SQL参数。图3为通过静态分析定位Android应用SQL注入相关SQL方法及SQL参数的流程图。对于应用的class文件以及依赖的jar文件,首先需要对字节码进行控制流分析。控制流表示程序的单个语句、指令或者函数调用的顺序,通过有向图表示控制流,形成控制流图。控制流图表示了程序执行过程中所有可能遍历的路径,它的每个结点是一个基本块,有向边指明了基本块间的执行关系。控制流只能从基本块中的第一个指令进入该块,除了基本块的最后一个指令,控制流在离开基本块之前不会停机或者跳转[14]。确定了基本块之后,就可以根据条件或无条件转移指令来识别基本块间的前后流通关系,以此建立字节码文件的控制流图。
Fig.3 Process of locating SQL method and parameter based on static analysis图3 基于静态分析的SQL方法及参数定位流程
有了控制流图之后,可以对程序进行进一步的数据流分析。数据流分析是一种用于获取程序中数据是如何沿着程序执行路径进行流动的信息的技术。在数据流分析中,通过对一组约束求解,就可以得到每个点上的数据流值,可分为基于语句语义约束和基于控制流约束。本文采用的是基于控制流约束方法,即在基本块之内时,每条语句输出的数据流就是下一条语句输入的数据流。在基本块之间时,每条控制流边都对应着新的约束,通过反复计算使系统达到稳定。
根据定义的SQL注入漏洞模型,遍历所有方法的控制流图,关注其中用于方法调用的指令,定位使用SQL方法的位置信息。对SQL方法的参数进行数据流分析,定位每个SQL参数的位置、参数标识等信息。可以定位程序中调用的所有SQL方法,以及每个SQL方法对应的SQL参数信息。定位SQL方法和SQL参数后,调用静态污点分析功能,分析对应的SQL参数是否来自外部输入。对于使用了外部输入作为参数的SQL方法,需要进一步验证程序中是否针对其SQL参数进行过合法性检查。
3.2 面向SQL注入漏洞的污点分析
本文提出的静态检测SQL注入漏洞方法的核心就是对程序进行静态污点分析。本文使用的程序静态分析部分是基于FindBugs使用的BCEL框架,可对应用的字节码进行处理。静态污点分析通常可分为过程内污点传播和过程间污点传播两类。考虑到部分应用会使用特定的数据结构来存储数据,如数组、Map等,增加了特殊数据结构污点传播。下面将分别对3种静态污点传播规则进行介绍。
3.2.1 特殊数据结构污点传播规则
对于外部输入的数据,很多程序都是选择直接通过字符串进行存储和修改。但是,除此之外,有时会使用特定的数据结构来存储数据,如数组、Map等。下面分别为数组结构、实现Collection接口和Map接口的类中的污点传播规则。
(1)数组结构
对于数组结构,可以将其视为一个整体进行处理。如果将一个污点数据传递给数组的一个元素,那么就将整个数组都标记为污染,而不是只将该索引位置标记。然后,对污染数组的所有读写操作都会将污染传播。
如图4中所示的代码片段,字符串taintStr为污染数据,在第3行将其赋值给数组spreadArray的第2个元素时,将整个spreadArray标记为污点数据。然后在第4行将spreadArray的第一个元素赋值给字符串str时,虽然之前并没有将污点数据赋值给spreadArray[0],但是整个spreadArray数组空间都被标记为污染了,因此str也会被标记为污点数据。
Fig.4 Array taint propagation图4 数组污点传播
(2)Collection接口和Map接口
Java语言中定义了Collection和Map作为所有集合和Map类的接口,开发者可以通过实现这些接口的子类来更加方便地组织复杂的数据,如List、Hash-Set、TreeMap等。因此,本文方法也要对这些结构体进行污点传播处理。这些结构体的污点传播规则与数组类型相似,也是将结构体当作一个整体进行污点标记,即只要将一个污染数据传递给结构体,就将整个结构体视为污染。然后对于点运算符“.”,取最左边对象的污染信息,如a.b.c的污染信息即为a的污染信息。
3.2.2 过程内污点传播规则
过程内污点传播是以方法为单位进行的。图5为过程内污点分析的流程,对于每个方法,需要一个污点数据集实时记录方法中的污点信息。先初始化污点数据集,并将参数污点信息和与外部输入有关的方法、变量加入污点数据集。然后遍历程序,根据指令类型进行相应的操作:对于变量读取指令,记录变量的污点信息;对于普通赋值指令,若之前读取了污点数据,则该指令把污点数据赋值给当前变量,并将该变量加入污点数据集;对于特殊结构体读写指令,进行特殊数据结构污点传播;对于方法调用指令,若该指令调用子方法,则进行过程间污点传播,若其对结构体进行操作,则进行特殊数据结构污点传播,若其是预先定义好的配置文件中的方法,表示其会把污点标记从参数传播到方法返回值,则将返回值加入污点数据集;对于方法返回指令,其是方法中最后一条指令,在记录方法的参数和返回值的污点信息后,输出整个污点数据集。其算法描述如算法1。
算法1过程内污点传播算法
输入:CFGcfg,Fileconfig//污染源配置文件JavaClassjavaclass//字节码文件
输出:HashSetTaintSet//方法污点数据集
3.2.3 过程间污点传播规则
本文采用的过程间污点传播规则为:对于进行了过程内污点传播的方法,传播结束时会记录此方法的参数和返回值污点信息。因此,首先分析被调用方法参数,若是之前扫描过该方法,且参数污点信息相同,则直接获取扫描时返回值的污点信息;否则,将参数的污点信息传递给被调用方法,对其进行过程内污点传播,然后将其返回值的污点信息返回给调用该方法的位置。其算法描述如算法2所示。
算法2过程间污点传播算法
输入:Methodcall//源方法
Methodcalled//子方法
HashMapAnalysisedMap<StringpamInfo,StringresultInfo>//记录进行过程内污点分析的方法的参数和返回值污点信息,pamInfo为方法调用时参数污点信息,resultInfo为方法返回值污点信息
输出:Stringresultinfo//子方法返回值污点信息
1.获取子方法called参数污点信息paminfo
Fig.5 In-process taint propagation图5 过程内污点传播
3.3 合法性检查
对于使用了来自外部输入参数的数据库执行方法,还无法确定其中确实存在SQL注入漏洞。若应用中对数据库查询语句的参数进行过合法性检查,就可以避免出现SQL注入的问题。因此,在进行污点分析以后,还要判断应用中是否对使用了污点数据的SQL方法中的SQL参数进行过合法性检查。常见的合法性检查的方法有以下几种:
(1)参数化方法。很多数据库都提供了参数化的方法,使用这些方法执行SQL语句时,数据库服务器先是对SQL指令进行编译,然后再将参数代入,而不是将参数也当成语句的一部分。因此,即使参数中存在恶意片段,也不会被数据库执行。比如Android应用中可以使用compileStatement方法,将其中外部输入都用“?”代替,然后通过相应的bind方法对参数进行配置,这样就不会存在SQL注入问题。
(2)白名单验证。若开发者已经知道某些形式的参数不会导致SQL注入漏洞,则可以在执行数据库操作前将参数与这些安全的形式进行验证。比如通过Pattern.matcher与事先定义好的模式进行匹配,或者通过String提供的方法判断参数中是否存在敏感字符等。而本文在扫描前两层基本块中,若是执行到调用了白名单验证使用的方法,且其参数为正在检测的数据库执行语句的污点数据参数,就认为程序中对这条SQL方法进行过合法性检查。
(3)过滤、转义敏感字符。实现过滤或转义敏感字符的一个常用方法就是使用replace之类的方法对表1中的敏感字符进行操作,如图6中第6行使用的Matcher.replaceAll方法。当扫描的前两个基本块中包含对敏感字符的过滤或者转义处理,也能认为应用中进行了合法性检查。
如算法3所示,本文只考虑使用了污染数据的SQL方法所在基本块及前两层的所有基本块,扫描这些基本块中是否对指定的SQL参数进行过合法性检查。如图6中的代码片段,第10行中的SQL方法rawQuery位于基本块B4中,且其参数sql为污点数据。则先检查B4在执行该方法前是否对sql进行过合法性检查,若没进行过就依次扫描上一层基本块B3、B2,若上一层仍未进行合法性检查,就再依次扫描两层前的基本块,该示例中仅有基本块B1。最终,若SQL方法所在基本块及前两层基本块都未进行过合法性检查,则可以认为这个使用了污点数据的SQL方法存在SQL注入漏洞。在这个示例中,位于基本块B3的第6行代码进行了合法性检查,则第10行的数据库执行方法是安全的。
Fig.6 Examples of legitimate check图6 合法性检查示例
算法3合法性检查判断
输入:Fileconfig//合法性检查相关方法配置文件
Stringpam//SQL方法中使用的污染参数
CFGcfg,Methodmethod,Locationloc
输出:Boolean//是否进行过合法性检查
4 工具实现与实验
4.1 原型工具实现
在Java代码静态分析工具FindBugs的基础上,本文实现了基于污点分析的Android应用SQL注入漏洞静态检测原型工具SQLInj。SQLInj首先静态分析Android应用的字节码文件,在程序中定位SQL注入漏洞的SQL方法和SQL参数,然后通过静态污点分析技术检测SQL语句中的污点数据,最后判断程序是否对SQL方法中使用的污点数据进行过合法性检查来报告是否存在SQL注入漏洞。如图7所示,SQLInj的总体框架主要分为程序静态分析、污点分析及合法性检查3个模块。
4.1.1 程序静态分析
FindBugs中实现了对字节码的控制流分析,在控制流图基础上,能得到每条指令的数据流信息。FindBugs中提供了很多种数据流信息,如当前指令所活跃的数据是否为常量、空值等,本文使用ConstantDataflow和ValueNumberDataflow来判断参数是否为常量字符串及其名称,并对FindBugs中提供的ValueNumberDataflow相关方法进行了修改,使得在进行ValueNumber数据流分析后,能同时获取局部变量和全局变量的名称。
4.1.2 静态污点分析
静态污点分析需要两个配置文件:source.config和derivation.config。其中,source.config文件中记录了与污染源有关的方法,在静态污点分析中,根据其配置污染源并初始化污点数据集。derivation.config文件中是能够将污点标记从污染数据传播给新数据的方法。首先,按照配置文件识别污染数据;然后,根据污点传播规则将所有被外部输入影响的方法和变量进行标记;最后,判断当前的SQL方法是否使用了被污染的参数。
4.1.3 合法性检查
在配置文件legimacy.config中定义了3.3节中所介绍的合法性检查相关的方法。根据合法性检查判断规则,如果使用了污点数据的SQL方法所在的基本块以及前两层的基本块中使用过legimacy.config文件中定义的方法,即认为程序中对这条SQL方法进行过合法性检查。
Fig.7 General framework of SQLInj图7 SQLInj总体框架
4.1.4 检测结果报告
当扫描完程序所有字节码文件后,SQLInj会输出最终的SQL注入漏洞检测结果,报告所有SQL注入漏洞的SQL方法所在的类、方法、在源文件中的具体行数,以及具体是哪一个数据库执行方法等信息。图8为检测结果报告中的一条错误信息示例,从中能够看到该SQL注入漏洞发生在MainActivity类的SQLInjectTest方法中,漏洞产生的原因是在此方法中将一个污染数据传递给SQL方法android.database.sqlite.SQLiteDatabase.rawQuery,该SQL方法位于源代码MainActivity.java的第118行。
Fig.8 Example of SQLInj detection result图8 SQLInj检测结果示例
4.2 实验设计与分析
使用SQLInj检测只需要Android应用的APK文件,但由于需要确认误报情况,因此实验选择了SQLInject、sieve等6个确定存在SQL注入漏洞的开源Android应用进行实验。如表2所示,6个实验对象的规模从500行到20 000行不等,表2中的第3列给出了应用功能的简要描述。
为评估本文所使用方法在检测SQL注入漏洞上的有效性,扩展了FindBugs原有的SQL漏洞注入检测功能,在不改变其检测机制的基础上,使其能够支持检测Android应用SQL注入漏洞。将FindBugs运行的结果与SQLInj的结果进行对比,可以验证使用污点分析及合法性检查判断对检测结果精度的影响。
4.3 实验结果分析
表3是SQLInj对6个应用的检测结果,其中已知漏洞为每个应用中已知存在SQL注入漏洞的SQL方法数量,污染方法是进行静态污点分析发现使用了污点数据的SQL方法的数量,疑似漏洞数是通过合法性检查判断后,存在SQL注入漏洞的SQL方法数量。然后,通过对每个应用中检测出的疑似漏洞进行判断,分析此处是否真实存在SQL注入漏洞。经分析确实存在的SQL注入漏洞为确认漏洞,未被检测到的SQL注入漏洞为漏报漏洞。表中第6列和第7列为SQLInj的漏报情况。实验结果表明,SQLInj在6个Android应用中共检测出35个SQL注入漏洞。对检测出的SQL注入漏洞进行检查发现,对其中4个应用的分析未出现漏报,2个应用的分析存在漏报,平均漏报率为9.1%。对产生漏报的原因进行分析发现,在进行污点分析时,为了提高分析效率,采取了记录执行过的过程内污点分析方法的参数及返回值等污点信息,当再次调用同一方法时,不再进行过程内污点分析,直接采用之前的污点分析信息。这一措施导致若某方法使用的全局变量在首次调用时与外部输入无关,但在之后的调用中与外部输入相关时,会产生漏报。实验结果表明,本文所使用的方法能有效检测出Android应用中的90%以上的SQL注入漏洞,漏报率较低。而FindBugs通过检测SQL方法的参数是否为常量字符串来判断此处是否存在SQL注入漏洞,因此基本不会发生漏报的现象,但精确度较低。
Table 2 Description of experimental objects表2 实验对象说明
Table 3 Detection results of SQLInj表3 SQLInj检测结果
SQLInj与FindBugs的误报情况对比如表4所示。使用FindBugs分析的误报率最低为33.3%,最高的达到85.1%,平均误报率为62.5%。使用SQLInj的误报率最低为0,最高为25.0%,平均误报率为7.5%。这是因为只要数据库执行方法的参数为诸如方法返回值、外部传参、字符串拼接等,FindBugs就会认为存在SQL注入漏洞,而SQLInj只有当SQL方法的参数与外部输入有关且未进行合法性检查时才认为存在SQL注入漏洞。SQLInj存在误报的原因是SQLInj不能检测出应用在SQL方法前两层基本块之前进行的敏感字符过滤等合法性检查,误报存在SQL注入漏洞。实验结果表明,本文所使用的基于污点分析的SQL注入漏洞静态检测方法有效降低了误报率。
Table 4 Comparison of false positive表4 误报情况对比
此外,还使用了综合评价指标来评价SQLInj和FindBugs检测结果的综合性能。将检测结果的确认漏洞称为TP,表示检测存在SQL注入漏洞且确实存在SQL注入漏洞的SQL方法数量。将疑似漏洞与确实漏洞的差称为FP,表示检测存在SQL注入漏洞,但其实是安全的SQL方法数量。将已知漏洞与确实漏洞的差称为FN,表示没有检测出但实际存在SQL注入漏洞的SQL方法数量。准确率P=TP/(TP+FP),表示被正确检测出的SQL方法中确实存在SQL注入漏洞的比例;召回率R=TP/(TP+FN),表示所有确实存在SQL注入漏洞的SQL方法中被正确检测出来的比例;综合评价指标F值F=2PR/(P+R),表示准确率和召回率的加权调和平均,综合了准确率和召回率的结果,有利于对检测结果综合性能的评价[15]。
SQLInj与FindBugs的综合评价标准F值对比结果如表5所示。FindBugs的F值最低为0.27,最高为0.80,平均值为0.53。SQLInj的F值最低为0.78,最高为1.00,平均值为0.91,比FindBugs高了约38%。因此,本文所使用的基于污点分析的SQL注入漏洞静态检测方法的综合性能更好。
Table 5 Comprehensive contrast between FindBugs and SQLInj表5 FindBugs与SQLInj综合对比情况
4.4 有效性影响因素分析
本文提出的方法能够有效地检测出Android应用中存在的SQL注入漏洞,并降低了误报率。但是该方法的效果仍受到以下方面限制:
(1)实验数据集的代表性。为了验证SQLInj检测结果的正确性,选择使用开源的Android应用进行实验,况且样本数量也还不够,需要提高实验数据集的代表性。
(2)本文方法仍存在漏报问题。主要原因为FindBugs按照调用树自底向上扫描方法所在class文件中的所有方法,这导致个别方法在被调用前就已经被扫描过了,当此方法被调用时若其所在类的全局变量曾被改变,将使得此方法返回值污染信息发生变化,但如果此方法参数的污点信息与第一次扫描时相同,不会再重新扫描,可能会产生漏报。此外,合法性检查不够精确也可能会导致漏报。通过扫描SQL方法前两层基本块中是否进行了合法性检查来判断是否存在SQL注入,若程序中进行了合法性检查,但检查条件并不准确,可能会导致检查后SQL参数中仍存在会导致SQL注入的字符串,从而引起漏报。
(3)本文方法仍存在误报问题。只扫描SQL方法前两层基本块中是否进行了合法性检查,当程序中合法性检查的位置与SQL方法距离较远时,可能会产生误报。
5 相关研究现状
由于SQL注入漏洞的风险性以及普遍性,如何检测SQL注入漏洞的问题引起了很多国内外学者的关注,目前已经做出了大量的研究工作,主要分为静态分析和动态测试两大类。另外,因为本文方法主要基于污点分析技术,所以对使用污点分析的相关工作也进行了总结。
5.1 静态分析技术
程序静态分析是不需要程序实际运行,而是在编译时就获得程序的相关属性,在此基础上对程序进行分析的技术。文献[16]对近几年使用静态检测SQL注入的方法进行了分析。符号执行技术是静态分析的一种,用来决定是哪些输入导致程序每个片段执行的分析方法。当使用符号执行来分析程序时,程序将符号作为值赋给变量,对程序的路径进行模拟执行,精确分析程序的代码属性[2,17]。文献[18-19]使用静态方法检测Web应用中的SQL注入漏洞,文献[20-22]则是通过静态方法针对Android应用进行检测。
除此之外,Coverity[5]和FindBugs[9]是使用较多的静态软件质量及安全漏洞检测工具。其中,Coverity使用过程间静态分析、字节精度分析、虚假路径剪枝等技术对软件源码进行静态分析,并提供了完整的路径覆盖,确保每一行代码以及潜在的执行路径都能被测试;FindBugs则是对应用的字节码文件进行数据流分析,并与漏洞缺陷模式进行匹配。但是,两者的SQL注入漏洞检测功能主要是针对Web应用的,无法对Android应用进行检测。
5.2 动态分析技术
动态分析技术是将程序在真实或虚拟机上运行,并对运行过程进行分析的方法。在静态分析中,有很多情况被认为是可能发生的,但在动态分析中,其分析的路径都是动态执行,确实发生了的,并且可以观察到程序运行时的状态。Chess和West在2008年提出了一种检测漏洞的动态分析方法[23]。在SQL注入问题上,也有很多方法是使用动态分析技术检测的,如文献[24-26]是动态检测Web应用中的SQL注入漏洞,文献[27]则将动态技术应用到检测Android应用上的SQL注入。
5.3 污点分析技术
污点分析可以分为静态和动态污点分析两种。文献[28-29]使用静态污点分析技术检测Android应用中的安全漏洞,文献[30]则提出一种在Java虚拟机中的动态污点分析方法,并结合了静态分析方法来收集可到达的方法,以减少运行时开销。在Android应用污点分析中,FlowDroid[10]和TaintDroid[31]是两个具有代表性的工具。FlowDroid是一款针对Android应用的上下文、流、字段、对象敏感和生存周期感知的静态污点分析工具,但其不支持SQL注入漏洞的检测。TaintDroid则是通过动态污点分析跟踪信息流的流动,但只会显示数据流动信息,而不会对漏洞进行检测。
6 结束语
本文针对Android应用中的SQL注入漏洞,提出一种基于污点分析的SQL注入漏洞静态检测方法。该方法首先对应用进行静态分析,在程序中定位SQL注入漏洞的SQL方法和SQL参数;然后通过静态污点分析方法检测SQL方法是否使用了污点数据;最后识别应用中是否存在对污点数据进行过合法性检查。基于上述方法,实现了原型工具SQLInj,并对存在SQL注入漏洞的Android应用进行了实验。
在本文研究的基础上,计划进一步研究如何通过JPF-Android等工具自动产生SQL注入攻击,以验证SQL注入漏洞的存在,并在检测出SQL注入后,尝试在源码中进行漏洞修复。