经过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令java
危害:数据库信息泄露mysql
恶意字符:1 or 1='1'等web
案例:sql
package com.zhiwei.database; import java.sql.*; public class PrepareStatementTest { public static void main(String[] args) { PreparedStatement ps =null; ResultSet rs=null; Connection ct=null; try { Class.forName("com.mysql.jdbc.Driver"); ct = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test","squirrel","xiaoyang"); ps=ct.prepareStatement("select *from user where name='zhangsan' and '1' or 1='1'"); rs=ps.executeQuery(); while(rs.next()){ int id =rs.getInt(1); String name = rs.getString(2); String passwd = rs.getString(3); int age=rs.getInt(4); String sex=rs.getString(5); System.out.println(id+"--"+name+"--"+passwd+"--"+age+"--"+sex); } } catch (Exception e) { e.printStackTrace(); } finally{ try { if(rs!=null){ rs.close(); }if(ps!=null){ ps.close(); }if(ct!=null){ ct.close(); } } catch (SQLException e) { e.printStackTrace(); } } } }
控制台日志:数据库
1--zhangsan--zhangsan--10--F 2--lisi--lisi--20--M 3--wangwu--wangwu--15--M 4--maliu--maliu--13--F 5--tianqi--tianqi--18--M 6--maba--maba--19--F 22--BBBB--BBBB--16--M
数据库记录:服务器
结果:优化
sql语句没有查出咱们想要的数据记录,而是将全部的表的记录都查询出来了,形成数据泄露(典型的sql注入漏洞)ui
分析:日志
select *from user where name='zhangsan' and '1' or 1='1'code
sql语句中and的优先级高于or的优先级,所以 select *from user where name='zhangsan' and '1' or 1='1' 等价于: select *from user where (name='zhangsan' and '1') or 1='1' 因name='zhangsan' and '1' or 1='1'的最终结果都是为真,where条件就失去做用,整条sql的功能等价于:select *from user
sql优化语句:
select *from user where name='zhangsan' and ('1' or 1='1')
分析 :
将恶意sql字符隔开,根据()的优先级大于and,所以整个sql语句的判断条件就变成name='zhangsan'和('1' or 1='1'),而('1' or 1='1')永久为真,所以整条语句就实现了对name的过滤做用,恶意sql则变得多余,但这样的sql并无实际的使用价值
注意:Mybatis中 $ 只是简单的变量替换存在sql注入风向, # 会将sql语句预编译,防止sql注入