张冰琦 孙 伟
1(中山大学软件学院 广州 510006)2(中山大学信息科学与技术学院 广州 510006)3(信息技术教育部重点实验室(中山大学) 广州 510006)(sunwei@mail.sysu.edu.cn)
一种基于污染源追踪的PHP源代码SQL注入漏洞检测算法
张冰琦1,3孙 伟2,3
1(中山大学软件学院 广州 510006)2(中山大学信息科学与技术学院 广州 510006)3(信息技术教育部重点实验室(中山大学) 广州 510006)(sunwei@mail.sysu.edu.cn)
SQL注入攻击被列为OWASP(open Web application security project)2010年和2013年十大Web应用系统安全威胁之首.SQL注入攻击检测及如何提高Web代码对SQL注入攻击的防御能力是目前常见的研究问题之一,结合词法分析及PHP语言特性,提出基于规则及特征匹配的漏洞检测架构,实现了PHP源代码的静态检测算法.测试结果表明该算法效果较好,具有较低的误报率,能够在词法分析阶段进行一定的别名分析及污染分析,从而在程序实现初期提高代码的安全性;同时漏洞检测框架可以进行拓展,实现对其他“taint-style”类型的漏洞检测.
SQL注入;词法分析;静态分析;污染分析;规则匹配
SQL注入攻击(SQL injection attack, SQLIA)通过在原始查询语句中注入新的SQL关键字或操作从而改变原先SQL查询语句的执行结果,常见于Web应用.此类攻击与跨站脚本攻击(cross-site scripting),简称为XSS,同为“污染类型”(taint-style)[1]的安全漏洞,产生此类攻击的根本原因为不充分的用户输入验证.针对此类型安全漏洞,如何有效地检测及追踪用户未经验证或过滤的输入,这是解决此类问题的关键,因此污染源追踪这是解决此类问题的有效方法之一.污染源追踪有3个重要的元素,即污染源、敏感函数及净化操作;其中污染源指代码中接受用户输入的语句,例如PHP中将$_POST变量赋值给变量的操作;敏感函数指代码中将被污染的变量送至数据库进行相关数据库操作的部分,例如PHP中的mysql_query函数语句;而净化操作则指代码中用于进行污染值净化操作的语句,例如进行特殊字符转义的函数mysql_escape_string等.
对于SQL注入攻击,研究人员提出一系列检测及防御机制,例如Livshits等人[2]使用污染分析,通过使用source,sink,derivation这3类描述符对所关注的Java源代码漏洞进行描述,从而通过静态代码分析查找潜在的、符合描述的代码漏洞,其中source描述符描述代码中接受用户输入数据的语句,对应于污染源追踪的污染源元素;sink描述符描述程序中数据不安全的使用方式,对应于污染源追踪的敏感函数元素;derivation描述符描述数据如何在程序的对象中传递;Livshits等人使用指针分析(pointer analysispoints-to analysis)对代码中的污染值传播路径进行分析.
Jovanovic等人[1]实现了针对PHP的漏洞检测工具Pixy,Pixy通过使用源文本分析(literal analysis)、别名分析(alias analysis)及污染分析(taint analysis)相结合,通过在代码中定位特定位置的污染值,之后确定污染值的传播路径,通过检测敏感函数是否接受污染值从而判断是否存在污染值与数据库进行交互,从而实现相关漏洞的检测.Jovanovic等人[1]使用数据流分析进行污染分析,对于数据流分析中的2个基本元素:“格”及“转换函数”分别进行分析.Jovanovic等人[1]在漏洞检测部分没有考虑PHP面向对象的特性,将对象成员方法或成员变量假设为“未被污染的”,在别名分析阶段,没有考虑成员变量及成员方法与全局变量、局部变量之间的别名关系;其次,没有考虑PHP中的数组及数组元素的别名关系,从而使得其检测结果存在一定的误判率.
其他相关的漏洞检测研究成果包括AMNESIA[3]结合静态分析及动态检测,在静态分析阶段收集源代码中所有的热点(hotspot),即代码中与数据库进行交互的代码语句,之后对每一个热点可能遇到的合法SQL查询语句进行建模,在动态检测阶段,对于动态生成的SQL查询语句,将其与静态分析阶段的模型进行比较,当无法与模型匹配时则该SQL查询语句可能已被注入,拒绝该SQL查询语句在数据库中执行;此类防御方法主要受限于其静态分析阶段所建立模型的准确性;WebSSARI[4]通过数据流分析,在程序中定位污染源,跟踪污染值的传递路径,并检测是否有污染值被运用于特定敏感函数,从而分析如何通过使用过滤器或过滤函数保证数据库操作的安全性,此类防御方法的局限性为默认污染值在经过特定的净化处理之后不再具有污染属性;Valeur等人[5]提出使用入侵检测系统进行漏洞检测,使用一系列典型的SQL查询进行机器学习,为典型的查询建模并对运行时的应用进行监控,从而辨认无法与模型相匹配的查询,此方法的局限性为其检测的准确性依赖于机器学习中的训练集合的质量.
PHP语言是最为常用的脚本语言之一,SQL注入攻击在使用PHP语言进行开发的Web应用中较为常见,因此本文提出了一种针对PHP源代码的基于污染源追踪的漏洞检测算法,通过词法分析及规则匹配对用户的输入进行检测及追踪,之后将检测到的漏洞以报告的形式提供给开发人员,从而提高Web应用的安全性.
在PHP中最为重要的概念为别名(alias).在PHP中,2个变量可以通过使用引用操作符(&)为2个变量建立别名关系(alias-relationship),该操作符可以直接运用至赋值或与函数形式参数或实际参数相结合,进行传引用调用(call-by-reference),引用即不同的名字可以访问同一个变量内容.在PHP中变量名和变量内容是不一样的,因此不同的变量可以指向同一个内容.结合本文的使用场景,污染分析无法离开别名分析,例如当变量$a接收用户输入的数据,当变量$b通过引用操作符与变量$a互为别名关系时:$b=&$a,则此时变量$a与$b皆是被污染的;若没有进行别名分析则会产生漏判.
已有的别名分析工作包括Anderson[6],Steensgaard[7]及Lam[8]等人的方法,其中大部分方法皆是针对C语言或者Java语言等编写的,因此大部分分析方法无法通过转换直接运用于PHP,原因包括:1)C语言和Java语言中的指针与PHP中的引用为完全不同的概念.C语言中的指针指保存内存地址的特殊变量;而PHP的引用则是符号表别名,而不直接存储内存地址,即PHP变量之间的别名关系是通过符号表的等价关系来表示的,而不是通过是否存储相同的内存地址来识别2个变量是否互为别名关系.2)PHP是动态决定类型,意味着PHP代码中变量的类型将不会在程序源码中明确声明,具体的类型是在执行时动态决定的,并且可以在程序执行过程中被改变;在PHP中,所有变量Zend默认为引用,甚至是仅仅包含标量值(scalar value)的变量也默认为使用引用实现;在参数传递方面,PHP语言的引用与C语言的指针也有所不同,在C语言中,当2个变量指向相同的内存地址,在源码中无论何时一个变量的值发生变化,另一个变量由于指向相同的内存地址,即其所指向的内存地址中的值发生变化时,则该变量的值也同时发生变化;在PHP中,引用的值是可以变化的,对于源码:
$x1=1;
$x2=2;
a($x1);
function a(& $p){
$p=&$GLOBALS[‘x2’];
}
由于$x1与$p只是符号表的别名关系,因此在函数a中对$p进行更改,只有$p的值发生变化时才会指向全局变量$x2指向的内容,$x1的值将不会被更改;Nenad指出此类问题在其写论文时尚未被解决,只有Liu等人提到对Python程序使用指针分析算法进行分析.本文所实现的检测工具将会使用“域”的概念解决此类别名问题,即默认函数的形参属于该函数的局部变量,在上述例子中,由于变量$p属于函数a的局部变量,而变量$x1属于全局变量,因此当$p值发生变化时,仅会对与其处于相同作用域的、且具有别名关系的变量产生影响,全局变量$x1值并不会发生变化.
过程内(Intraprocedural)的别名分析较为简单,对于过程间(Interprocedural)的别名分析有一个难点:即如何处理递归函数调用.由于每一个被调用的递归函数都包含其自身的一份局部变量拷贝(variable incarnations),即对于每一个递归函数内部的每一个局部变量,该函数每被调用一次就会产生关于特定调用的该变量的一份拷贝;在大多数情况下,从代码静态分析的角度无法直接决定一个递归函数的递归调用链的深度,因为其调用链的深度取决于一些动态的属性,例如取决于数据库返回的数据或用户的相关输入;因此静态分析需要面临“无限”个数的变量“化身”,结合污染分析,该特性意味着污染分析底层所用的“格”将会无限增加高度,即污染分析将不会终止,因此Jovanovic等人[1]提出一个原则作为别名分析的基础原则:在函数体内,别名分析只追踪关于全局变量及其自身的局部变量的化身.即在全局域内只考虑全局变量,该原则使得分析过程中只会产生有限数量的变量,本文在过程间的别名分析中采纳Jovanovic等人提出的该原则,在函数内部进行别名分析及污染源追踪时,仅考虑全局变量及该函数自身的局部变量,以此简化问题.
对于过程间分析,由于考虑函数调用,有上下文相关的过程间分析及上下文无关的过程间分析2种:上下文相关的过程间分析能够区分同一函数的不同调用;而上下文无关的过程间分析仅能够区分不同函数的调用,不能区分同一函数的不同调用;2种分析结果相比较,上下文相关的过程间分析具有较高的精确度.本文实现的静态代码检测工具是通过记录相应函数调用的具体位置以区分同一函数的不同调用,实现上下文相关的过程间分析,从而使污染分析更为可靠.
PHP中“域”的概念对于变量值的追踪十分重要.PHP从“域”的角度来看有2种类型的变量:局部变量,即出现在函数的局部域中的变量;以及全局变量,即出现在全局域内的变量,在PHP中等价于在函数作用域外的变量;函数的形参属于局部变量一类.在函数内,全局变量的访问有2种方式:第一种方式为通过关键字“global”,使用该关键字相当于声明局部变量$a与全局变量$a互为别名关系;第二种方式为使用特殊的$GLOBALS数组,该数组在程序的任意处皆可见;通过使用$GLOBALS数组,全局变量甚至可以在函数内被重新引用到新值,使用关键字“global”则没有这样的功能.本文仅提供对“global”关键字的支持,暂不提供对$GLOBALS数组的支持.在进行过程间别名分析时“域”的概念十分重要,对于全局变量之间的别名问题、被调用函数的形参之间的别名问题、全局变量与被调用函数的形参之间的别名问题、全局变量及调用者的局部变量之间的别名问题都需要进行单独的分析,从而为别名分析之后的污染分析建立基础,降低漏判率及误判率.本文通过对变量的“域”属性进行区分,对此4类别名问题进行分析,从而在此别名分析基础上进行以下污染分析:
1) 对于全局变量之间的别名问题,由于全局变量的作用域均为全局,因此污染值可以在全局变量之间进行传递,对于全局变量$a及$b,若$b被污染,且$a=&$b,则$a亦成为被污染的,变量$a与$b互为别名关系;全局变量之间的别名关系将会被完整地传递到被调用的函数中;
2) 对于被调用函数的形参之间的别名问题,此类情况只有当函数的形参之间存在别名关系时发生,例如对于函数b的2个形参$bp1及$bp2,两者都是通过引用传递,对于变量$b1,$b2,当$b1=&$b2成立时,若使用语句b($b1,$b2)进行函数b的调用,由于$b1与$b2互为别名关系,则形参$bp1与$bp2也互为别名关系;此时若变量$b2是被污染的,则$b1也是被污染的,在此处被调用的函数b中,形参$bp1与$bp2同样为被污染的;本文实现的检测工具暂不提供此类别名关系的检测;
3) 全局变量与被调用函数的形参之间的别名问题,由于全局变量的别名关系及污染值将会被完整地传入被调用参数,且当函数的形参与实参具有引用赋值关系时,则相应的形参与实参之间具有别名关系;则对于全局变量$a1,当$a1为被污染时,则此时若使用$a1作为实参进行函数调用,且相应形参为引用赋值,由于两者具有别名关系,则函数对应的形参也为被污染的,此时在函数域内,与形参互为别名关系的变量同样为被污染的;
4) 全局变量及调用者的局部变量之间的别名问题,由于调用者的局部变量之间的别名关系无法被被调用者所改变,但是被调用函数有可能改变调用者的局部变量或全局变量的引用值;则被改变的变量将会根据新值是否为被污染而进行处理;例如$GLOBALS数组的使用,由于该数组内元素在程序任意处可见,且可以被重新引用赋值,若所赋的新值为被污染的,则该变量值为被污染的,此时若调用者的局部变量与该全局变量有别名关系,则其局部变量将成为被污染的.本文暂不考虑此类情况.
2.1 模式匹配
模式匹配为提供一系列匹配条件规则,对于给定的一个字符串,在其内容中寻找可以匹配的模式,当一个匹配确定之后,执行该匹配模式对应的相关操作.相应的原理描述如下:已知长度为n的文本字符串:S=S1S2S3…Sn和一长度为m(m≤n)的模式字符串:T=T1T2T3…Tm,之后在字符串S中搜索是否存在长度为m的子串:Si-1Si-2Si-3…Si-m,使得Si-j=Tj,j=1,2,3,…,m,i≤n-m;将模式T和文本S从左至右逐个搜索,若在某一位匹配失败,则将模式T向右移动1位,仍从模式T的第1位重新开始搜索.
例如在词法分析程序生成器Flex中,一系列匹配模式是通过正则表达式定义,当Flex生成的扫描程序(Scanner)运行时,它将对其输入内容进行分析,从而找到符合某一个匹配模式的字符串;若同时符合多个匹配模式则采取贪婪算法匹配最长的那个模式;若2个模式匹配的长度相同,则匹配在Lex中最新定义的那个模式;当确定所匹配的模式时,扫描程序将会记录被匹配的单词(Token)的长度,并使该单词对于全局可见(使用一个全局指针指向该单词);之后继续对剩余的文本进行模式匹配;若当前没有一个规则匹配,则执行默认的规则:即默认下一个字符是匹配的,并输出至标准输出.对于每一个模式规则都可以有一个对应的操作,当相应规则匹配之后将会执行该操作;若该操作为空则规则匹配之后不会进行任何操作.
本文在规则库中通过对源代码词法分析之后生成的单词(Token)设计相应匹配规则,从而对源代码进行污染分析;之后在知识库中对匹配的规则进行收集及整理,对于每一个所匹配规则对应的代码漏洞类型设计相应的代码修补建议,之后以报告的形式反馈至开发人员.
本文所实现的静态代码检测工具通过使用词法分析得到的单词序列(Token)构造所需的过滤规则,通过制定过滤规则并进行模式匹配实现PHP源代码的别名分析及污染分析,即使用规则库进行污染源、敏感函数、净化操作的检测,并进行污染值传播路径的追踪.过滤规则所检测的操作包含简单赋值、一元赋值、二元赋值及引用赋值,并考虑PHP面向对象的特性,对公有成员变量的赋值操作进行污染值追踪;暂不考虑面向对象的成员方法与全局变量、局部变量之间的别名关系;对于PHP的数组,本文实现的静态检测算法将考虑数组间的别名关系及其污染值传递,暂不考虑数组元素之间的别名关系及其污染值传递,例如当一个存有污染值的数组通过引用赋值给另一个数组时,本文提出的检测算法可以检测到该别名关系并对该污染值进行追踪;当一个存有污染值的数组元素被引用赋值给另一个变量或数组元素,本文提供的算法暂时无法检测到该别名关系及相关污染值的传播,由于以上原因,使得本文的静态代码检测算法存在一定的误判率.
3.1 算法架构
本文所实现的静态代码检测工具主要基于一个开放及可拓展的架构,利用词法分析、别名分析及规则匹配进行污染源的检测及其传播路径的追踪,最终在分析结束后给相关人员输出漏洞缺陷报告,其架构如图1所示.
图1 静态检测算法架构图
架构主要由输入、处理引擎和输出3部分组成,其功能特点如下:
1) 输入.由代码和规则库组成,规则库将根据输出的知识库和漏洞缺陷警告等信息进行改进.
2) 处理引擎.由代码预处理、漏洞过滤、警告生成、知识生成等各个功能组件构成,具有良好的扩展性和稳定性;本文实现的漏洞检测工具重点实现了代码预处理、漏洞过滤、警告生成3个功能组件.
3) 输出.由知识库和漏洞缺陷警告组成;知识库的意义是生成有价值的知识,指导开发人员提高编程质量,同时也对规则库的完整性和准确性提供支持.本文漏洞检测工具实现了漏洞缺陷警告功能,知识库的提出为下一步研究提供了接口和思路.
3.2 相关定义
在本文提出的漏洞检测算法中,其中V表示PHP代码中存在的变量集合;T表示PHP代码词法分析之后得到的Token集合;F表示PHP代码中可能存在的变量的属性或变量的字段集合;使用S表示变量或属性所属的域,域值为“global”或函数名或方法名,当域值为函数名或方法名时,则表示该变量为此函数的局部变量;使用L表示程序中函数或方法被调用的位置;N表示PHP代码中被调用的方法名或函数名;M表示PHP代码中用户自定义的函数名或方法名;Z表示方法或函数所使用的参数.之后定义以下8种关系:
vR(variable:V,tokenT,scopeS)
vRF(variable:V,field:F,tokenT,scopeS)
LE(invocation location:L,method:M,scopeS)
Store(base:V,field:F,source:V,scopeS)
load(base:V,field:F,dest:V,scopeS)
assign(dest:V,sourceV,scopeS)
actual(invocation location:L,parameter:Z,variable:V,scopeS)
formal(method:M,parameter:Z,variable:V,scopeS)
在上述8种关系中,variable表示变量集合;token表示变量对应的Token集合;scope表示域值.域值可分为2种,即全局或函数局部变量,当为全局变量时,域值为“global”;当为函数局部变量时,域值为对应函数名或方法名,域值对于之后的污染传播路径追踪较为重要,默认store,load及assign关系均为当变量处于相同域时才可识别.
vR作为8种关系的基本关系,vR(v,t,s)表示域值为s的变量v在词法分析之后对应于Tokent;vRF(v,f,t,s)表示域值为s的变量v的字段f在代码词法分析之后对应于Tokent;store表示变量值存储至变量的字段中,store(v1,f,v2,s)对应的代码语句为:v1.f=v2,且2个变量的域值皆为s;load表示在变量的字段中加载另一个变量的值,且2个变量的域值皆为s,load(v1,f,v2,s)对应的代码语句为:v2=v1.f;assign表示变量之间的赋值,assign(v1,v2,s)所对应的代码语句为:v1=v2,除了一般的赋值关系,assign也包括引用赋值类型的检测,由于引用赋值仍然属于赋值的一种,因此与其他类型赋值关系统一用一种关系表示;LE(l,m,s)表示方法m在l处被调用,且该方法所属域为s;actual(l,z,v,s)表示变量v在调用位置l被作为参数z的实参进行传递,且实参v所属作用域为s;formal(m,z,v,s)表示函数或方法m的参数z用变量v表示,即v为形参,所属作用域为s;注意函数的形参将作为函数的局部变量,即其域值为对应的方法名;之后定义8种规则进行模式匹配:
R1:vR(v,t,s)
R2:vRF(v,f,t,s)
R3:vR(v1,t,s):assign(v1,v2,s),vR(v2,t,s)
R4:vRF(v1,f,t,s):store(v1,f,v2,s),vR(v2,t,s)
R5:vRF(f,v1,t,s):load(v2,f,v3,s),store(v1,f,v3,s),vRF(v2,f,t,s)
R6:vRR(v1,s1,v2,s2)
R7:LE(l,m,s)
R8:vM(v1,m,v2):LE(l,m),formal(m,z,v1,s1),actual(l,z,v2,s2)
其中R1及R2两个规则分别用于检测变量、变量的字段与词法分析之后的Token的对应关系,此规则用于检测用户输入数据的存储,例如当PHP代码从PHP代码的超全局变量$_POST获取数据时,即可通过该规则检测到相应的代码;R3规则由2个关系组成:assign(v1,v2,s)及vR(v2,t,s),表示由于v2在代码词法分析之后与Tokent相对应,而代码中出现了v1=v2的语句,因此v1在赋值语句之后也与Tokent对象相对应,在实际中,若变量v2存储了用户输入的数据,则赋值语句之后,变量v1存储的数据也是用户输入的数据,从而发现用户输入数据的值传递;R4规则vRF(v1,f,t,s)及R5规则vRF(f,v1,t,s)表示域值为s的变量v1的字段f对应于Tokent,2个规则结论相同但值传递路径不相同,路径传递解释带入相应关系即可;规则R6表示s1作用域的变量v1与s2作用域的变量v2有别名关系,即v1=&v2,当s2作用域的v2变量值为污染值时,s1作用域的v1变量值同样为污染的;R7表示方法或函数m在l处被调用,调用时所在作用域为s,该规则主要用于检测被调用的函数或方法;R8规则vM(v1,m,v2)表示函数或方法m的形参为v1,实参为v2,两者存在别名关系,其中s1为形参所属的作用域,s2为实参所属的作用域;需要对实参进行污染检测从而判断形参是否已被污染;当实参被污染时,形参及函数作用域中与形参具有别名关系的变量均为被污染的.
3.3 算法实现
本文实现的SQL注入漏洞检测算法主要分为2部分:一部分为别名分析,另一部分为污染分析,总体算法流程如下:
1) 遍历存储的Token集合,获取所关注的Token类型,例如T_VARIABLE,T_STRING,T_FUNCTION及T_BITWISE_AND等,为关注的Token类型设置监听器;
2) 当监听器获取到其所监听的Token类型时,进行以下处理,对于所有关注的Token类型对应的监听器:
① 通过规则库获取指定规则库或使用默认规则库通过关键字查询,获取当前Token相关的过滤规则;
② 通过规则匹配进行漏洞过滤,当出现当前Token所匹配的规则时,记录当前Token的相关信息.
3) 将所有满足过滤规则的漏洞信息进行格式化,生成漏洞报告输出,并同时处理知识生成存储至知识库.
算法中Token对象将会以关联数组形式储存Token对象的相关信息,包括Token对象对应的代码行号、列号、Token对象的内容、Token类型的名称等,存储此类信息主要是为了进行漏洞代码定位时能够为开发者提供充足的信息,以便漏洞修补.
在上述总体算法流程基础上,对于别名分析,本文实现的检测工具提供以下3种情况下的别名关系检测:1)变量之间的别名关系,包括全局变量之间及局部变量之间的别名关系;2)函数形参与全局变量之间的别名关系;3)数组之间的别名关系.在以上3种别名关系的基础上进行污染分析.
对于污染分析,本文实现的检测工具提供对5种操作类型的检测:简单赋值、一元赋值、二元赋值、引用赋值及公有成员变量的赋值操作,其中简单赋值为通过“=”等号为变量进行赋值,一元赋值操作符op在PHP源代码中形如“$a=op $b”,其中一元操作符不包括“&”操作符;一元操作符作用于变量之后,变量$a是否被污染将取决于变量$b是否为污染值以及一元操作符的具体类型,例如对于加号“+”、减号“-”等,当其作用于被污染的字符串类型变量$b时,$a的值将会成为数值类型的值,因此污染值被“净化”;而对于强类型转换“(string)”操作符,由于不知道变量$b是否被污染,因此无法判断$a变量的值是否被污染,因此赋值后的变量$a是否被污染取决于变量$b是否被污染,若$b被污染,则$a同样被污染;相关一元操作符及其作用后变量$a的污染值情况如表1所示:
Table 1 Taint Analysis of the Unary Operators
二元操作符的分析与一元操作符类似,二元操作符包括算术运算操作符、字符串连接操作符、逻辑操作符、比较操作符、位移操作符及按位逻辑操作符,其中字符串连接操作符及按位逻辑操作符,当2个源操作变量其中之一包含污染值时,则目的操作变量为“被污染的”,其余二元操作符均有“净化”作用,相关二元操作符及其作用后目的操作变量的污染值情况如表2所示:
Table 2 Taint Analysis of the Binary Operators
表1及表2皆参考了文献[1]及文献[8]的相关内容;对于引用赋值符号“&”,对应的Token类型为“T_BITWISE_AND”,本文实现的引用赋值类型检测包括2种情况:变量之间的引用赋值以及函数形参与实参之间的引用赋值;对于面向对象的公有成员变量的赋值操作,通过对“→”符号(T_OBJECT_OPERATOR)的监听来进行赋值操作的识别及污染值的追踪.
本文通过选择了DCP Portal 6.1.1中的68个PHP文件及本科生课程设计的个人博客项目wmblog的12个PHP文件进行别名分析及污染分析,实验结果如表3所示:
Table 3 Test Results
以上实验结果是通过本文实现的代码检测工具对目标文件进行检测,之后通过人工检查PHP源代码判断是否误判.由以上实验结果可以看出,误判率为8.16%,是否误判主要依据为是否对过滤规则正确地进行模式匹配;由于本文所定义的规则有限,因此存在尚未定义过滤规则的污染值传递情况,例如类成员方法内的污染值传递及数组元素间的污染值传递情况,对此类污染值传递过程暂不进行考虑,因此本文实现的漏洞检测工具具有一定的漏判率.
4.1 类的公有成员变量的污染值检测
对图2所示的特定代码段进行检测,漏洞报告内容如图3所示;由漏洞检测报告可知,该代码段中接收用户输入的变量被成功检测,并成功对其污染路径进行追踪,本示例证明本文实现的静态代码检测算法能够对PHP面向对象的特性提供一定的支持,能够成功对类的公有成员变量进行污染值传播路径的追踪.
图2 PHP源代码段示例
图3 PHP源代码检测结果示例
图4 PHP源代码示例
4.2 全局变量及局部变量的污染值检测
对图4所示的代码段进行检测,漏洞检测结果如图5所示.由漏洞检测报告可知,对于全局变量及函数作用域内的局部变量,本文实现的代码检测工具能够正确进行别名分析,并在污染值追踪过程中能够正确区分不同作用域的变量,从而保证全局变量及局部变量相同变量名时污染分析能够正常进行.
图5 PHP源代码检测结果示例
4.3 函数调用的污染值检测
对图6所示的代码段进行检测,漏洞检测结果如图7所示.由检测结果可得,本文实现的代码检测工具能够对自定义函数的形参及实参进行正确的别名分析,并能够对不同作用域的变量进行正确的别名分析及污染值追踪.
图6 PHP源代码示例
图7 PHP源代码检测结果示例
本文针对常见的SQL注入攻击及防御方法进行总结,并对PHP语言特性进行分析,之后提出了基于规则匹配的PHP源代码SQL注入检测算法,该算法利用PHP词法分析之后产生的Token序列,结合PHP语言特性,对用户输入制定一系列的过滤规则,对用户未经过滤或净化操作的输入进行检测及追踪,生成漏洞缺陷报告,并生成相应知识进行知识库的构建.本文提出的检测算法经实验证明,具有较低的误报率,但由于该算法基于词法分析,在此阶段进行别名分析及污染值的追踪将会受到词法分析特性的限制,且定义的过滤规则有限,因此算法具有一定的漏报率.在未来的研究中,将会进一步完善规则库和知识库的搭建,并通过结合语法分析阶段的污染检测算法从而降低误报率及漏报率,并进一步提供对其余“污染类型”的Web漏洞检测功能.
[1]Jovanovic N, Kruegel C, Kirda E. Static analysis for detecting taint-style vulnerabilities in web applications[J]. Journal of Computer Security, 2010, 18(5): 861-907
[2]Livshits V B, Lam M S. Finding security errors in Java programs with static analysis[C] //Proc of the 14th USENIX Security Symp. Berkeley: USENIX Association, 2005: 18-18
[3]William G, Halfond J. Alessandro Orso. AMNESIA: Analysis and monitoring for neutralizing SQL-injection attacks[C] //Proc of the 20th IEEE/ACM Int Conf on Automated Software Engineering. New York: ACM, 2005: 174-183
[4]Huang Y, Yu F, Hang C, et al. Securing Web application code by static analysis and runtime protection[C] //Proc of the 13th Int Conf on World Wide Web (WWW’04). New York: ACM, 2004: 40-52
[5]Valeur F, Mutz D, Vigna G. A learning-based approach to the detection of SQL attacks[C] //Proc of the Conf on Detection of Intrusions and Malware and Vulnerability Assessment (DIMVA). Berlin: Springer, 2005: 123-140
[6]Steensgaard B. Points-to analysis in almost linear time[C] //Proc of the 23rd ACM SIGPLAN-SIGACT Symp on Principles of Programming Languages (POPL’96). New York: ACM, 1996: 32-41
[7]Wilson R P, Lam M S. Efficient context-sensitive pointer analysis for C programs[D]. Stanford: Stanford University, 1998
[8]谢亿鑫, 孙乐昌, 刘京菊. 基于数据流分析的SQL注入漏洞发现技术研究[J]. 微计算机信息, 2010, 26(5-3): 163-165
张冰琦
硕士研究生,主要研究方向为信息安全.
icy397@hotmail.com
孙 伟
教授,博士生导师,主要研究方向为网络安全和多媒体技术通信.
sunwei@mail.sysu.edu.cn
A PHP Source-Code SQL Injection Attack Detection Algorithm Based on Taint Tracking
Zhang Bingqi1,3and Sun Wei2,3
1(SchoolofSoftware,SunYet-senUniversity,Guangzhou510006)2(SchoolofInformationScienceandTechnology,SunYet-senUniversity,Guangzhou510006)3(KeyLaboratoryofInformationTechnology,MinistryofEducation(SunYet-senUniversity),Guangzhou510006)
The concept of “SQL injection” has been proposed for more than 10 years, however, SQL injection attack was still rated the number one attack on the Open Web Application Security Project(OWASP) in 2013. With the rapid development of dynamic Web applications, PHP becomes popular because it's fast, reliable and can be combined with many different types of RDBMS, and it's also a cheap option for developing and hosting applications on the Web. PHP is a powerful language which can access files, execute commands and open network connections on the server. However, these properties also make anything is run on a Web server insecure by default. As there are several ways of utilizing PHP, there are many configuration options controlling its behavior. A large selection of options guarantees that PHP can be utilized to a lot of purposes. With proper runtime configuration options and coding practices, PHP can provide exactly the combination of freedom and security. This paper considers the security risks related to PHP programming language, and describes different situations which will lead to website vulnerabilities. It also proposes a static lexical analysis framework for detecting SQL injections based on the matching rules, and implements the PHP source-code SQL injection attack detection algorithm. The experiments demonstrate that the algorithm is effective, and it can also be extended to detect other “taint-style” Web vulnerabilities.
SQL injection; lexical analysis; static analysis; taint analysis; matching rules
2015-10-06
广东省自然科学基金项目(S2013010013728);澳门科技发展基金项目(097/2013/A3)
TP393.08