SQL注入示例:
JAVA代码:
String sql = "select * from product where pname like '%'"
+ request.getParameter("pname") + "'%'";
conn.execqueryResultSet(sql);
构造SQL注入攻击代码
http://test.qunar.com/product.jsp?id=1' and 1= 2
uoion select 1, name, pass, 4 from user where "<>'
插入攻击代码之后的SQL语句
select * from product where pname like '%1' and 1= 2
uoion select 1, name, pass, 4 from user where "<>'
解决:
1)MyBatis使用时,SQL参数时统一使用#{},禁止使用${}
2)数据长度应该严格规定,能在一定程度上防止比较长的SQL注入语句无法正确执行。
3)确认每种数据的类型,比如数字型的数据就必须是数字,数据库中的存储字段必须对应为int型。
4)SQL注入需要输入‘ 和空格等字符,对进入数据库的特殊字符(’"<>&*;等)进行转义处理,或编码转换。
5)严格限制网站用户的数据库的操作权限,给此用户提供仅仅能够满足其工作的权限,从而最大限度的减少注入攻击对数据库的危害。
6)网站每个数据层的编码统一,建议全部使用UTF-8编码,上下层编码不一致有可能导致一些过滤模型被绕过。
7)使用PreparedStatement防止SQL注入
如果有一条SQL语句: “select * from 表 where 用户名 = ‘用户名’”
Statement的SQL语句是这样写的:
“select * from 表 where 用户名 = '”+ 变量值 +"’"
PreparedStatement的SQL语句是这样写的:
“select * from 表 where 用户名 = ?” 然后对应?赋值
输入 “aa’ or ‘1’ = '1”
Statement是将这个和SQL语句做字符串连接到一起执行,和最上边一样的形式。
PreparedStatement是将 “aa’ or ‘1’ = '1” 作为一个字符串赋值给?,做为"用户名"字段的对应值,显然这样SQL注入无从谈起了.