金鑫 卫文学
摘要:SQL注入是目前Web应用程序攻击中最常见的一种攻击手段,但没有一种防御方法可以防止全部类型的SQL注入攻击。文章结合实例对SQL注入攻击进行简单介绍并对其进行分类,总结目前常用的防御方法。最后,文章提出数据加密防止SQL注入攻击的方法,通过加密算法加密数据库数据和所有用户输入,改变用户输入的原意进行防御,并给出实际应用中防止SQL注入攻击的建议。
关键词:SQL注入;数据库;参数;前台;后台
中图分类号:TP393.08 文献标识码:A 文章编号:1009-3044(2015)20-0004-02
SQL Injection Attack and Prevention
JIN Xin1, WEI Wen-xue2
(School of Information Science and Engineering, Qingdao 266590, China)
Abstract: SQL injection is one of the most common attacks in Web application attacks, but there is no defense against all types of SQL injection attacks. This paper briefly introduces the SQL injection attacks and classifies them into a practical example, it summarizes the commonly used methods of defense. Finally, the article proposes the method of data encryption to prevent SQL injection attack, through the encryption algorithm to encrypt the database data and all user input, to change the original intent of the user input, and gives the practical application to prevent SQL injection attacks.
Key words:SQL injection; database; parameter; foreground; background
1 引言
随着计算机和互联网技术的发展,计算机网络服务趋于多样化,Web应用程序日益流行。然而由于互联网的开放性以及部分程序员的能力和经验缺失,Web应用程序又经常存在安全问题,Web数据库容易受到攻击。Web应用程序数据库的安全问题已经成为网络安全亟待解决的问题之一,而SQL注入攻击是Web应用程序攻击中最常见的一种。
2 SQL注入攻击简介
SQL注入是一种通过SQL代码嵌入到Web应用程序输入的参数中,然后将这些参数与后台SQL命令进行拼接,并最终在SQL数据库进行解析、执行的攻击。
2.1 SQL注入攻击过程
攻击者进行SQL注入攻击首先要确定Web应用程序中是否添加了验证,是否能够注入,这一过程就是寻找注入点的过程。这一过程中一般可以通过插入单引号、插入延迟命令或者使用注入工具等方法确定注入点。确定注入点后攻击者会在Web应用程序前台插入参数,待参数传递到后台后与程序中的SQL语句拼接成一条或多条新的SQL语句。新的SQL语句会经程序处理后提交的数据库进行编译并执行,从而引发SQL注入攻击。一般来说攻击者攻击Web应用主要是为了获取数据,这时数据库会将数据返回到前台展示,造成信息泄露。极少数特别恶劣的攻击会删除数据表甚至摧毁整个数据库,导致Web应用程序丢失数据。SQL注入攻击过程如图1 SQL注入过程所示。
图1 SQL注入过程
2.2 SQL注入攻击简单实例
一般的WEB应用程序前台登陆页面包括用户名、密码和验证码。用户输入用户名、密码和验证码后点击登陆,输入的数据会传到后台与已经编写的SQL语句拼接,最后数据库执行SQL语句查询此用户信息。假设后台已编写的SQL语句为select * from user where username=xxx and password=xxx,并且程序没有添加验证,在前台用户名传参已知的用户Y,密码传参Y or ‘1 =1,则前台参数与后台已编写SQL语句拼接为select * from user where username= Y and password= Y or ‘1 =1。 新的SQL语句在数据库执行后会返回Y用户的所有信息,并成功登陆Web应用程序。
3 SQL注入攻击常见的类型
3.1 字符串内联注入
字符串内联注入是指查询的参数类型为字符串类型,在前台注入一些SQL代码后,原查询仍然全部执行。通常,该查询的格式如下:select * from admin where username = ‘xxx and password = ‘xxx。
字符串类型的查询可以通过在前台输入单引号来确认是否存在注入点,确认存在注入点后在前台输入参数传到后台拼接SQL语句完成注入攻击。例如,在上面的SQL语句的username处输入一个单引号,那么SQL语句将变为select * from admin where username = ‘ and password = ‘。显然,SQL语句出现了语法错误,如果前台未进行错误处理,将会直接返回SQL语法错误到前台页面。确认此注入点后要做的就是在前台输入参数,字符串内联注入时输入的参数中一般包含一个永真条件和SQL关键字“or”。这里与SQL注入攻击简单实例类似,可以查询已知用户的所有信息,也可以在username和password处都输入Y or ‘1 =1,查询所有用户的所有信息。
3.2 数字值内联注入
数字值内联注入与字符串内联注入类似,是指查询的参数类型为数字值类型,在前台注入一些SQL代码后,原查询仍然全部执行。通常,该查询的格式如下:select * from messages where id = xxx。
数字值类型的查询确认注入点的过程与字符串类型的查询确认注入点的过程相同。与字符串内联注入类似,确认注入点后,数字值内联注入在前台输入的参数也一般包含一个永真条件和SQL关键字“or”。在上面的SQL语句的id处输入1 or 1=1,查询id为1的消息的所有信息。
3.3 终止式注入
终止式注入是指在注入SQL代码时,通过注释剩下的查询来成功结束该语句。终止式注入一般用在包含在多个参数的查询中,通过保证注释字符前面的成立,忽略注释后面的语句来实现注入。例如,在 SQL注入攻击简单实例的SQL语句username传参admin or ‘1=‘1--,password随便传值x,SQL语句变为select * from admin where username = ‘admin or ‘1=‘1-- and password = ‘x。显然,SQL语句有效部分变为select * from admin where username = ‘admin,即知道用户名即可获取该用户的所有信息并登录系统。
3.4 执行多条语句注入
执行多条语句注入是指终止一条SQL语句,创建一条全新的没有限制的语句。执行多条语句注入多用在破坏数据库系统。例如,假设知道user表存放登陆名和密码,后台SQL语句为select * from messages where id = x,攻击者在前台传参1 or 1=1;delete user,则新的SQL为select * from messages where id = 1 or 1=1;delete user。显然,一条SQL语句变为两条SQL语句,分号前面的语句是可执行的,而分号后面的语句具有很大破坏性,直接删除了整个user表。
4 SQL注入攻击常见的防御方法
4.1 前台输入验证
前台输入验证是对接收的参数进行检查,最大限度的保证符合定义的标准的过程。前台输入验证的理念是不相信用户输入,检查每个用户输入是否满足预设定的类型、长度或大小、数值范围和格式等。前台输入验证时可以使用只接受已记录在案的良好的输入的操作的白名单验证方法,也可以使用只拒绝已记录在案的不良输入的集合的黑名单验证方法。对于存在赋值输入情况或难以确定所有可能的额输入集合时,白名单验证比较困难;黑名单验证缺点是潜在的不良字符列表非常大,检索慢且不完全,并且很难及时更新。
4.2 后台输出验证
后台输出验证是对发往数据库的内容进行检查,通常是进行通配符的替换。以SQL Server为例,由于使用单引号作为字符串的结束符,所以要对包含在字符串中的单引号进行编码。假设后台SQL语句为select * from users where username=UN and password=‘PW,令UN取值已知的admin,PW取值1 or ‘1=‘1。显然,如果直接将新的SQL语句发往数据库会注入成功。这里添加后台输出验证,令PW = PW.replace(“ ”, “ “ ”),将字符串中的单引号替换为双引号,那么传到数据库的SQL语句将变为select * from users where username=admin and password= ‘1 or “1”=“1”,从而避免了注入的发生。
4.3 编码规范化
编码规范化是指拒绝所有不符合规范格式的输入。有时,攻击者会在将前台输入发送给后台之前对其进行编码,如果攻击者所用的编码格式恰巧与后台编码格式相同,则后台对前台输入进行解码后与已编写SQL语句拼接完成注入攻击。例如,%27是单引号的URL编码表示,%u0027是单引号的Unicode编码表示,这两种编码表示很容易绕过前台对单引号的输入验证,如果后台符合他们依赖的编码规范则又会被解释成“”。
4.4 SQL语句参数化
SQL语句参数化是指用占位符或绑定变量来向SQL查询提供参数的方法,是一种更加安全的动态字符串构造方法。Java、C#和PHP等语言都提供了参数化的类或方法。参数化方法可以防御绝大部分的SQL注入攻击,因为参数化查询可以重用执行计划,SQL语句所要表达的语义不会改变。然而,SQL语句参数化也有缺点,它只能参数化数据值,不能参数化标识符或关键字。例如,select * from ? where username=‘un 和select * from user where username like ‘j% order by ?这两条语句的格式就是错误的。
5 通过数据加密防止SQL注入攻击
用户的输入是SQL注入攻击的根源,所以常用的防御方法的原则是不相信用户输入,对用户的输入在前台、后台和数据库进行检查和修改。通过数据加密防止SQL注入的方法也是基于不相信用户输入这一原则,将所有用户输入都进行加密。
当前台输入要保存到数据库时,后台会将用户输入进行加密然后直接保存到数据库,不再解密到前台输入的状态;当前台请求查询时,后台会将用户输入进行加密然后直接到数据库中查询,同样不进行解密,当从数据库中返回查询结果到后台时再对数据进行解密,最终返回到前台页面。需要强调的是,数据库中保存的数据都是经过加密的数据。
通过数据加密,攻击者在前台输入的要攻击应用程序的参数就会改变原意。例如,在 SQL注入攻击简单实例的SQL语句select * from user where username=xxx and password=xxx中的username处传参1,password处传参1 or ‘1 =1,则SQL注入成功。然而通过凯撒密码的加密,1加密为2,1 or ‘1 =1加密为2<!ps!<2<><2,SQL注入失败。本例中的加密算法较为简单,实际应用时可选择任意的可逆加密算法,而且一个应用程序中可以使用多种加密算法。
6 总结
采用数据加密防止SQL注入攻击的方法优点是安全度高,攻击者注入成功的概率和用户随便输入注入成功的概率相同;缺点较为明显,因加密解密过程导致应用程序效率低。
实际上,由于SQL注入攻击的种类繁多,灵活多变,很难有一种方法解决全部SQL注入问题。SQL语句参数化方法可以解决绝大多数的SQL注入问题,而参数化方法不能应用的地方可以再采用数据加密防止SQL注入攻击的方法,这样既可以提高效率,又能保证应用程序安全性。
参考文献:
[1]徐寿怀,胡美琛. 数据库安全研究的现状与问题[J]. 计算机工程,1997(3):50-53.
[2]高洪涛. SQL注入攻击途径及策略分析[J]. 网络安全技术与应用,2011(3):14-16.
[3]薛昱春,黄东. 一种新的SQL注入攻击的防范方法[J]. 电脑知识与技术,2006(2):121-122.
[4] Justin Clarke .SQL注入攻击与防御[M] .北京:清华大学出版社,2010(6):46-57,270-292.
[5]张卓. SQL注入攻击技术及防范措施研究[D].上海交通大学,2007.5-6
[6]张勇,李力,薛倩. Web环境下SQL注入攻击的检测与防御[J]. 现代电子技术,2004(15):103-105.
[7]徐书欣,王希军. Web页面中SQL注入攻击过程及防御措施[J]. 信息技术,2014(8):187-189.
[8]隋励丽,张恒博. 基于参数查询防止SQL注入攻击的方法[J]. 大连民族学院学报,2012(5):495-497.