SQL注入漏洞
- SQL注入漏洞原理
SQL注入通常是攻击者通过操作来修改SQL语句,通过代码对Web服务器进行攻击。在程序管理员不知情的状况下对Web应用程序进行攻击,来获得用户名和密码等信息,进而获得数据库的权限。SQL注入漏洞目前较为常见,危害也较大。 - SQL注入万能密码原理
SQL注入漏洞中含有万能密码的原理是提交的字符没有过滤或者过滤不严格,从而不需要进行用户名验证或密码验证就可以进行登录,此时攻击者可能利用此漏洞来盗取信息。
在存在漏洞的网站,攻击者就可利用SQL注入漏洞绕过登录验证。如将SQL语句写为:SELECT * FROM Student WHERE name=’’AND PWD=1’or ‘1’=’1,因为赋值’1’=’1’是恒等式,所以永远正确。这种万能密码方式是跳过身份认证的简单手段。当使用了万能密码,用户输入的name用户名和密码都会失效,无论输入正确的信息还是错误的信息最终都可以成功登录,这就是典型的SQL注入。在用户登录界面,如图1所示,输入正确的用户名:张三,万能密码:1’ or’1’=’1此时成功进入登录后的学生考试查成绩界面,如图2所示。
![](https://i-blog.csdnimg.cn/blog_migrate/9888cee0c26a0cc140c3c8b8922d9351.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1c6e5b3923ad319b15f5190b25c32056.png)
SQL注入方法
- 数字型注入
数字型注入指的是当输入的参数为整型时,会出现数字型注入。对于登录界面的用户ID,当存在SQL注入漏洞时,可以认为是数字型注入。
在Web应用程序中,ASP属于弱类型语言,弱类型语言会自动推导变量类型。
在数据库中输入SQL语句:select * from Student where ID=2019001 and 1=1。因为1=1是恒等式,在数据库中可以查出Student表中ID号为2019001的用户信息,当在数据库中输入SQL语句:select * from Student where ID=2019001 and 1=2,此时SQL语句的语法是正确的,但是逻辑判断是错误的,查询不到Student表中ID号为2019001用户的信息。 - 字符型注入
当输入的参数为字符串时,称为字符型。字符型和数字型之间最大的区别是,数字型不需要单引号闭合,而字符串通常使用单引号闭合。比如在用户进行登录时,数据库会进行查询其SQL语句为:SELECT FROM Student WHERE name =’张三’ AND PWD =123 ;其中name字段是字符型注入。
用户将SQL语句写为:SELECT * FROM Student WHERE name ‘张三’ AND 1=1–’,后面加两个-,这意味它将后面的语句注释,让密码验证不起作用,这样语句永远都能正确执行,攻击者轻易骗过系统,获取合法身份。此时攻击者并未输入密码却能查询出密码来。
SQL注入漏洞还可以有更严重的危害,如删除数据库中的表其SQL语句如下所示:SELECT * FROM Student WHERE name= ’张三’ AND PWD=1’or ‘1’=’1 drop table Student,通过SQL注入漏洞攻击者可以将Student表删除掉,一旦攻击者利用此漏洞进行删除数据库里的信息对Web应用程序会造成极大的影响,会产生很严重的后果。
SQL注入漏洞的防御方案
为了防止SQL注入漏洞对于用户输入的内容或传递的参数值,要保持警惕。现总结防御方案如下。
- 检查变量数据类型和格式
当SQL语句为where id= {id}这种形式,对于数据库id这个字段存储的都是数字,当SQL语句被执行之前检查确保变量id是int类型;当使用邮箱时,应确保其输入的变量为邮箱的正确形式,如果需要时间、电话等信息也是同样的道理。在执行SQL语句时,若其有固定的格式应严格按照其标准来要求,并且要严格检查其格式,对于ID号应严格要求在用户进行注册时ID号只能是数字,不能输入其他特殊符号。此时应该有一个check_ ID的函数来进行统一的检查。
在SQL Server中,右击Admin表,点击设计->右击ID->选择CHECK约束->点击添加写表达式为((ID in (1,2,3,4,5,6,7,8,9)),此时,已成功对ID进行了约束。 - 过滤特殊符号与语法关键字
在Web应用程序中,有些符号是比较危险的,因此可以采用特殊符号过滤方法来处理无法确定的格式变量。
注释符号被过滤:使用or ‘1’ = ’2结尾的形式可进行绕过。其实注释本来的作用也就是闭合语句,只要抓住这个核心目标就行。比如目标参数是双引号包裹的,就可使用or’’ 1’’ =’’ 2的结尾进行绕过。需要注意,由于’-’是注释的一部分也被过滤掉了,会带来其他的一些副作用,因为’-’同时也是减号和负号。
空格被过滤:可以用%a0来替代空格分割语句。
and和or被过滤:可以用&&和||来替代。需要注意,这里也会发生歧义需要注意,比如password会被过滤成passwd,解决这个副作用的方法是双写or,也就是改用passwoorrd, passwoorrd中or被过滤掉之后就变成了password。 - 绑定变量
当相同类型SQL语句绑定变量时,SQL文本变得一样,此时减少了程序硬解析的次数。这里相同类型SQL语句是指除SQL文本中对应的输入值不同外其他部分均相同。 - 参数化SQL语句
参数化查询是指在当Web应用程序要访问数据库时,在需要填写ID和密码的地方使用参数传递值,当使用参数化查询,数据库不会立马对参数的内容进行处理,而是数据库将SQL语句编译完毕后,参数指令才会运行。攻击者想利用注入漏洞进行攻击,由于使用参数化查询,就算参数中有攻击语句,程序也已编译完成。使用参数化SQL语句是最为有效的防止SQL注入漏洞的方法。
使用参数化SQL语句步骤:
-适应@符号来表示参数,string sqlstr=’’ SELECT * FROM Admin WHERE ID=@ID AND PWD=@PWD’’。
-给SQL语句中的参数定义参数对象,用SqlPar ameter数组传递参数值:SqlParameter[] para = new SqlParameter[]{ new SqlParameter(“ @ID”, ID)}将查询语句中所需要的值传递给SqlParameter数组,再把值传递给cmd。通过参数传递可以避免SQL注入漏洞问题。 - 安全的数据库
SQL注入主要是攻击者通过构造巧妙的SQL语句对数据库进行一系列操作,有一个安全的数据库是十分重要的。人们常使用的数据库MySQL使用root和anonymous用户账户,SQL Server使用sa作为数据库系统管理员账户,当允许以root , sa等特权用户来执行操作,一旦数据库遭到攻击,将会有极大的破坏力。所以要谨慎分配这些用户权限。同时,使用安全的数据库账号,设置高强度的数据库密码等也可以保证数据库的安全。