什么是SQL注入
软件程序(包括web
)代码中对于用户提交的参数未做过滤就直接放到 SQL
语句中执行,导致参数中的特殊字符打破了 SQL
语句原有逻辑,有心人可以利用该漏洞执行任意 SQL
语句,如查询数据、下载数据,甚至是写入webshell
、执行系统命令以及绕过登录限制等。
SQL注入原理
SQL
注入漏洞的产生需要满足以下两个条件:
- 参数用户可控:从前端传给后端的参数内容是用户可以控制的;
- 参数带入数据库查询:传入的参数拼接到 SQL 语句,且带入数据库查询。
设定一个场景,当用户传入参数1‘
时,数据库会执行下面的指令:
select * from users where id = 1'
很明显该SQL
语句不符合语法规则,会出现下面的错误:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use
当用户传入参数为1 and 1 = 1
时,数据库会执行如下指令:
select * from users where id = 1 and 1 = 1
因为1=1
为真,id=1
也是真,and
两边均为真,所以页面会返回id=1
的结果。
假设用户传入参数为 1 and 1 = 2
,1=2
为假id=1
为真 ,and
两边有一个为假,所以页面返回与id=1
不一样的结果。
基于此,可以初步确定这里存在SQL
注入漏洞,攻击者可以进一步拼接 SQL
攻击语句,进行攻击,致使信息泄露,甚至获取服务器权限。
如何测试SQL注入
渗透测试主要结合渗透测试工具来检测软件程序是否存在漏洞,对于SQL
注入这类型的漏洞,我们可以使用到sqlmap
这个工具来进行检查或者利用,当然也可以使用其它相关类型的工具来测试,那个趁手用哪个!
最开始可以先手动测试,利用单引号、and 1 = 1
或者and 1 = 2
、字符型注入对测试点进行判断。
这里推荐使用burpsuite
里面的sqlmap
插件(使用方式自行百度):
简单的判断是否存在SQL注入
通常可以有两种场景,有回显的场景和无回显的场景,有回显的场景测试SQL
注入可以通过实际页面返回的数据对测试语句进行调整;无回显的场景判断比较困难,因为页面没有任何变化,或者没有数据库中的内容显示到网页中。
通常我们可以使用下面的测试语句对可能存在SQL
注入的点进行测试:
id = 1 and 1=1
id = 1 and 1=2
id = 1 or 1=1
id = '1' or '1'='1'
id = " 1 " or "1"="1"
SQL注入漏洞的修复建议
以下几条建议仅供参考:
- 所有的查询语句都使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到
SQL
语句中。当前几乎所有的数据库系统都提供了参数化SQL
语句执行接口,使用此接口可以非常有效的防止SQL
注入攻击。 - 对进入数据库的特殊字符(
' <>&*;
等)进行转义处理,或编码转换。 - 确认每种数据的类型,比如数字型的数据就必须是数字,数据库中的存储字段必须对应为
int
型。 - 数据长度应该严格规定,能在一定程度上防止比较长的
SQL
注入语句无法正确执行。 - 网站每个数据层的编码统一,建议全部使用
UTF-8
编码,上下层编码不一致有可能导致一些过滤模型被绕过。 - 严格限制网站用户的数据库的操作权限,给此用户提供仅仅能够满足其工作的权限,从而最大限度的减少注入攻击对数据库的危害。
- 避免网站显示
SQL
错误信息,比如类型错误、字段不匹配等,防止攻击者利用这些错误信息进行一些判断。
目前代码层最佳防御 SQL
漏洞方案:采用 SQL
语句预编译和绑定变量,是防御 SQL
注入的最佳方法。
本篇文章仅对SQL
注入进行简单的介绍,SQL
注入还有很多更深入的介绍后续再慢慢更新。