MySQL知识总结四(SQL注入)
MySQL知识总结一(MySQL常见术语)MySQL知识总结二(MySQL基本操作)MySQL知识总结三(MySQL查询数据)MySQL知识总结四(SQL注入)MySQL知识总结五(MySQL函数和运算符)
如果通过网页获取用户输入的数据并将其插入一个MySQL数据库,那么就有可能发生SQL注入安全的问题。
SQL注入:是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
常见的SQL注入
SQL注入分为很多种,有联合注入、布尔注入、报错注入、时间注入、堆叠注入、二次注入、宽字节注入、cookie注入等等等。
1、联合注入:利用union的联合查询。
如:“1’ union select 1, database()#”,(此时1后面需要单引号进行闭合;运用union select联合查询我们后面所要查询的字段个数要和之前一致;最后我们要用#注释掉后面的内容,然后使得自己输入的后的字符失效);
当获取了数据表之后,可以使用“1’ union select 1,concat(user,password) from users#”获取用户名和密码。
2、Boolean注入:页面返回的结果是Boolean型的,通过构造SQL判断语句,查看页面的返回结果是否报错,页面返回是否正常等来判断哪些SQL判断条件时成立的,通过此来获取数据库中的数据。
(利用一个个试错的方式,利用返回结果进行匹配。比如询问密码,利用sql内置的一些函数length(str)、substr(str,pos,len)等,可以先询问是不是某个字符,根据返回的结果true或false,判断自己的猜想是否正确,直到把所有位置的数据都询问出来,以达到获取数据的方式,很多时候这样的试错方式有脚本进行测试)。
3、报错注入:报错注入就是通过页面爆出的错误信息,构造合适的语句来获取我们想要的数据。
出现报错注入的原因:首先是应用系统未关闭数据库报错函数,对于一些SQL语句的错误,直接回显在了页面上,部分甚至直接泄露数据库名和表名;其次,必不可少就是后台未对MySQL相应的报错函数进行过滤,如:updatexml()、floor()、extractvalue()、exp()等。
4、堆叠注入:将一堆sql语句叠加在一起执行,使用分号结束上一个语句再叠加其他语句一起执行。
5、二次注入:是指已存储(数据库、文件)的用户输入被读取后再次进入到 SQL 查询语句中导致的注入。
网站对我们输入的一些重要的关键字进行了转义,但是这些我们构造的语句已经写进了数据库,可以在没有被转义的地方使用。可能每一次注入都不构成漏洞,但是如果一起用就可能造成注入。
二次注入触发条件:(1)用户向数据库插入恶意语句、(2)数据库对自己存储的数据非常放心,直接取出恶意数据给用户。
注意以下情形:
(1)在普通的登录页面,都会有输入用户名和密码。可以采用常见的在用户名处输入“admin’#”;
(2)如果上述没成功,说明对一些特殊字符进行了转义,做了过滤防护措施的;
(3)找到注册位置,注册一个账号:用户名“admin’#”; 密码“123456”;
(4)注册成功之后,可以在数据库中看见我们的用户信息;
(5)登录进去之后,修改我们账号的密码;
(6)再次插入的时候,用户名“admin’#”中的“#”会把后面的内容影响到,根据语句可能把用户名“admin”的密码给修改了
SQL注入的防御
1、采用预编译技术:使用预编译的SQL语句,SQL语句的语义是不会发生改变的(参数化查询)。预编译语句在创建的时候就已经将指定的SQL语句发送给了DBMS,完成了解析,检查,编译等工作,所以攻击者无法改变SQL语句的结构,只是把值赋给?,然后将?这个变量传给SQL语句。当然还有一些通过预编译绕过某些安全防护的操作。
2、严格控制数据类型:对强类型语言中一般不存在数字型注入,因为接收数字时,大多都会进行整型(int)数据类型转换。对于弱类型语言需要进行数字类型检查,防止数字型注入。
3、对特殊字符进行转义:字符型是无法通过类型转换防止注入的,对特殊字符进行转义。比如:MySQL中可以对“’”进行转义,也可以对“#”(注释)进行转义,这样防止了一些恶意攻击者来闭合语句。当然我们也可以通过一些安全函数来转义特殊字符。但是攻击者还是可以通过一些特殊的方式绕开。
4、二次注入的防御:(1)对外部提交数据谨慎;(2)数据库取数据时,不能轻易相信查询出的数据,要做到同样的转义或是甄别;
开发过程中可以避免 SQL 注入的一些方法:
1. 避免使用动态SQL:避免将用户的输入数据直接放入 SQL 语句中,最好使用准备好的语句和参数化查询,这样更安全。
2. 不要将敏感数据保留在纯文本中:加密存储在数据库中的私有/机密数据,这样可以提供了另一级保护,以防攻击者成功地排出敏感数据。
3. 限制数据库权限和特权:将数据库用户的功能设置为最低要求;这将限制攻击者在设法获取访问权限时可以执行的操作。
4. 避免直接向用户显示数据库错误:攻击者可以使用这些错误消息来获取有关数据库的信息。