参考:http://www.360doc.com/content/19/0827/12/37289152_857336899.shtml
参考:https://blog.csdn.net/dark_horse_lk/article/details/87074592
参考:https://www.cnblogs.com/zhidongjian/p/10413635.html
SQL只攻击Statement,对PreparedStatement无效的(不允许在不同的插入时间改变查询的逻辑结构)
验证用户是否存在的SQL语句。
其他 -- 为sql的注释。
select * from a where name='aaaa' or 1=1 //输出所有记录。
select * from a where name='aaaa' or 1=1 and login=1010 //无记录
select * from a where name='aaaa' or 1=1 -- and login=1010 //输出所有记录。
针对此,应对方法:
private String getNameByUserId(String userId) {
Connection conn = getConn();//获得连接
String sql = "select name from user where id=" + userId;
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs=pstmt.executeUpdate();
......
}
当传入的参数为:"3;drop table user;"时,
执行时的语句就是:select name from user where id=3;drop table user;
这对于数据来说是非常危险的。
1、使用PreparedStatement
Connection conn = getConn();//获得连接
String sql = "select name from user where id= ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, userId);
ResultSet rs=pstmt.executeUpdate();
......
还是上边的参数:"3;drop table user;"
最后执行语句就会是:select name from user where id="3;drop table user;"。 避免了sql注入。
2.使用正则表达式过滤传入的参数
3.字符串过滤
4 mybatis自动化框架
在编写MyBatis的映射语句时,尽量采用“#{xxx}”这样的格式。若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止SQL注入攻击。
#{}:相当于JDBC中的PreparedStatement
${}:是输出变量的值
简单说,#{}是经过预编译的,是安全的;${}是未经过预编译的,仅仅是取变量的值,是非安全的,存在SQL注入。