针对SQL注入的策略研究
2016-07-23赵星
赵 星
(中北大学 软件学院,山西 太原 030051)
针对SQL注入的策略研究
赵星
(中北大学 软件学院,山西 太原 030051)
摘要:在计算机技术高速发展的今天,让人们头疼的是面临越来越多的威胁网站的技术。近年来,SQL注入事件频发,本文主要介绍了SQL注入及其危害,并提出了使用预编译语句,过滤URL中传参等安全策略以消除SQL注入的存在,可进一步提高网站安全。
关键词:网络安全;SQL注入;防护
在计算机技术高速发展的今天,让人们头疼的是面临越来越多的威胁网站的技术,黑客们利用Internet执行各种恶意活动,如身份窃取、私密信息窃取、带宽资源占用等。近年来,SQL注入事件频发,例如某网站的会员信息泄露事件,造成的损失不可估量,本文主要介绍了SQL注入以及如何防止SQL注入,可进一步提高安全意识。
1SQL注入及SQLMap工具介绍
注入漏洞是Web安全领域中一种最为常见的漏洞。许多Web应用系统采用某种数据库,接受用户从Web页面中输入,完成展示相关存储的数据(如检查用户登录信息)、将输入数据存储到数据库(如用户输入表单中数据域并点击提交后,系统将信息存入数据库)等操作。在有些情况下,将用户输入的数据和设计好的SQL框架拼接后提交给数据库执行,就可能存在用户输入的数据并非设计的正确格式,从而给恶意用户提供破坏的机会,即SQL注入。SQL注入攻击的本质就是拼接了用户输入的代码,并予以执行,涉及到两个关键的因素:第一就是用户可以随意输入内容;第二就是原本程序要执行的代码拼接了用户输入的数据。
SQLMap是一个自动化的SQL注入测试工具,是一款开源软件,其主要功能是扫描、发现并利用给定的URL的SQL注入漏洞,目前支持的数据库是MySQL,Oracle,PostgreSQL,Microsoft SQL Server,Microsoft Access,IBM DB2,SQLite,Firebird,Sybase和SAP MaxDB。当给SQLMap这么一个URL的时候,它会判断可注入的参数(包括GET参数,POST参数,HTTP Cookie参数);判断可以用哪种SQL注入技术来注入;识别出哪种数据库;根据用户选择,读取哪些数据。SQLMap采用五种独特的SQL注入技术,分别是:
1) 基于布尔的盲注,即可以根据返回页面判断条件真假的注入。
2) 基于时间的盲注,即不能根据页面返回内容判断任何信息,用条件语句查看时间延迟语句是否执行(即页面返回时间是否增加)来判断。
3) 基于报错注入,即页面会返回错误信息,或者把注入的语句的结果直接返回在页面中。
4) 联合查询注入,可以使用union的情况下的注入。
5) 堆查询注入,可以同时执行多条语句的执行时的注入。
2SQL注入的危害及SQLMap工具演示
恶意用户输入不期望的数据,拼接后提交给数据库执行,可能造成数据泄露,还可能修改数据库的结构,甚至删除应用的数据库表等严重后果。如某系统实现时,对成绩更新所用的SQL语句如下:
“UPDATE StuScore SET score=“+ SubmitScore +” WHERE StuID=‘ “+ StuID + ” ‘ ; ”
当用户输入的SubmitScore为90--,StuID为20150001时,则该SQL变为:
“UPDATE StuScore SET score = 90 -- WHERE StuID = ‘20150001‘;”
--在SQL中是注释符号,以后的内容为注释,这样上述语句中--之后的内容变为注释,只要是StudentScore表中所有的记录的score都变为90,而没有受到WHERE字句后的学号限制。
再比如SubmitScore为80,StuID为20150001’ or ‘a’ = ‘a’时,则该SQL语句变为:
“UPDATE StuScore SET score = 80 -- WHERE StuID = ‘20150001‘ or ‘a’ = ‘a’;”
因为’a’ = ‘a’条件总是成立,因此,SQL执行结果把所有在StuScore表内同学的成绩都更新为80分。
更严重的情况下,用户输入DROP等功能性命令,会造成数据库表的永久删除等严重后果,如StuID为20150001;DROP TABLE StuScore --,则SQL语句变为:
“UPDATE StuScore SET score = 80 -- WHERE StuID = ‘20150001‘; DROP TABLE StuScore --”;
手工测试是一个繁琐的过程,可以借助自动化的注入工具SQLMap高效地完成注入测试,首先检查该站点是否存在注入:python sqlmap.py-u URL(将URL替换成真实测试地址),会得到类似图1的效果,通过工具很容易判断出存在哪种类型的注入,注入点相关信息,以及数据库系统信息。
图1 注入点信息
通过此注入点,可以进一步探测存在哪些数据库,命令为python sqlmap.py -u URL-databases,如图2所示。
图2 存在数据库
选定数据库后,可查看其中存在的数据表,命令为python sqlmap.py -u URL -D DB -tables,如图3所示。
然后判断表中存在哪些字段以及字段的数据值,这样直接可获取数据库内的信息,包括一些核心敏感信息,如后台管理员用户名和密码,用户的隐私数据,如图4所示。
3防御措施
未知攻焉知防,了解攻击的目的是为了更好地防御,针对SQL注入攻击的防御措施如下。
3.1使用预编译语句
防御SQL注入的最佳方式就是使用预编译语句,进行变
图3 数据表信息
图4 敏感信息
量绑定。因为使用预编译后的SQL语句的语义不会发生改变。在SQL语句中使用?表示,攻击者无法改变SQL的结构。下边用PHP代码演示变量的绑定过程。
$query = “INSERT INTO StuScore (StuID ,Name ,Sex ,Score) VALUES(?,?,?,?)”;
$bind = $mysqli -> prepare($query);
$bind -> bind_param(“test” ,$stuID,$name,$sex,$score);
$stuID = “20150001”;
$name = “Zebra”;
$sex = “male”;
$score = “60”;
$bind -> excute();
在JAVA语言中有与PHP类似的预编译语句,在JAVA中有个类是PreparedStatement,这个类的对象是通过参数?来传值的,例:
String sql = "select * from table where id = ?";
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1,id);
这里的数据库语句所用到的参数要被设置的,如果你传入了错的值,或不同类型的值,它在插入到数据库语句中会编译不通过,这样也就防止了SQL注入。
3.2使用安全函数与安全编码
为了防止SQL注入攻击,PHP自带一个功能可以对输入的字符串进行处理,可以在较底层对输入进行安全上的初步处理,即Magic Quotes。如果magic_quotes_gpc选项启用,那么输入的字符串中的单引号,双引号和其它一些字符前将会被自动加上反斜杠/。
但Magic Quotes并不是一个很通用的解决方案,没能屏蔽所有有潜在危险的字符,并且在许多服务器上Magic Quotes并没有被启用,所以需要使用其它多种方法来防止SQL注入。
现在各类Web语言都实现了一些编码函数,可以用来对抗SQL注入。比如在MySQL中,可以按照以下思路对字符进行编码:
“(0x22)-->”
‘(0x27)-->’
(0x5c)-->
同时可以参考OWASP ESAPI中的实现。
3.3过滤URL传参的变量
在PHP程序中,我们可以使用str_replace()函数对字符串变量的内容进行字符替换。
语法如下:str_replace(“需要替换的字段”,”替换为的字段”,”字符串内容”);套用到上面的例子中,假如我们需要过滤掉”and”我们可以这样写:
$id = $_GET[‘id’];
$id=str_replace(“and”,””,$id);
这样一来,变量id字符串中的”and”被替换为空字符,可以理解为被删除了。在不同的使用环境下,某一个程序需要替换十几个字符。所以需要使用数组的方式,将字符替换封装为一个函数,便于在任何时候调用它。
字符替换函数核心代码[1]如下:
function fliter_sql($value) {
$sql = array(“select” , ”insert” , ”update” , ”delete” , ” ’ ” , ”/*” , ”../” , ”union” , “into” );
$sql_re = array(“”,””,””,””,””,””,””,””,””);
return str_replace($sql, $sql_re, $value);
}
这是经常使用的过滤函数,通过它基本上可以过滤掉绝大多数的SQL注入。使用的时候只需要调用这个函数,$id = fliter_sql($_GET[“id”]);即可。
3.4检查数据类型
检查数据类型对于防止数字型注入有很大的帮助,特别是在强类型的语言中。比如在下边这段代码中,就限制了输入数据的类型只能为integer,在这种情况下,一般的注入攻击将失效[2]。
Settpye($offset , ‘integer’);
$query = “SELECT score,id FROM StuScore ORDER BY id LIMIT 10 OFFSET $offset;”;
检查数据类型对防错是大有裨益的,比如用户在输入邮箱时,可以使用正则表达式对输入的格式加以验证,输入时间、日期时,必须严格按照时间、日期的格式等等,这样做的目的是为了防止对用户数据的破坏。
4总结
SQL注入攻击是违背了数据与代码分离原则导致的,它有两个条件:一是用户能够控制数据的输入,二是原本程序要执行的代码拼接了用户输入的数据,并把数据当作代码执行了。针对可能存在的SQL注入问题,本文提出了使用预编译语句,过滤URL中传参等安全策略以消除SQL注入的存在。通过设计和实施合理的安全解决方案,注入攻击是可以彻底杜绝的。
参考文献
[1]吴翰清.白帽子讲Web安全[M].北京:电子工业出版社,2014.
[2]张炳帅.Web安全深度剖析[M].北京:电子工业出版社,2015.
收稿日期:2015-11-10
作者简介:赵星(1990- ),男,安徽人,研究生,研究方向:网络安全。
文章编号:1674- 4578(2016)02- 0041- 02
中图分类号:TP309.2
文献标识码:A
Strategies for SQL Injection
Zhao Xing
(SoftwareCollege,NorthUniversityofChina,TaiyuanShanxi030051,China)
Abstract:For today’s rapid development of computer technology, the problem for people is facing more and more threat technology to the Website, the SQL injection events frequently occur. This article introduces the SQL injection and its hazards, and proposes the use of pre-compiled statement, URL filtering and other security policies to eliminate the existence of SQL injection which can further improve the site security.
Key words:cyber security; SQL injection; protection