所谓SQL注入式攻击,就是输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令。在某些表单中,用户输入的内容直接用来构造(或者影响)动态SQL命令,或作为存储过程的输入参数,这类表单特别容易受到SQL注入式攻击。
导致原因及可能后果
通过将带有恶意目的的SQL语句或参数写入表单中进行提交,程序未经过校验直接执行SQL语句,导致一些敏感数据泄露包括一些用户名密码信息等,以及可能会对数据库信息进行增删改操作,篡改数据等严重后果。
一些例子
直接动态拼接SQL语句
反例:
String username = request.getParameter("username");
String password = request.getParameter("password");
String encryptedPass = PasswordUtil.encrypt(password);
String sql = "select * from users where username = '" + username + "' and password = '" + encryptedPass + "'";
Statement s = c.createStatement();
ResultSet rs = s.executeQuery(sql);
正例:
String username = request.getParameter("username");
String password = request.getParameter("password");
String encryptedPass = PasswordUtil.encrypt(password);
String sql = "select * from users where "
+ "username = ? and password = ?";
PreparedStatement s = c.prepareStatement(sql);
s.setString(1, username);
s.setString(2, encryptedPass);
ResultSet rs = s.executeQuery();
如果用户登录时候在username和passwor分别填入
username = "‘1' or '1'='1‘";
password = "’1' or '1'='1’";
最终SQL语句就会变成
String sql = "select * from users where "
+ "username = '1' or '1'='1' and password = '1' or '1'='1'";
由于where条件永为真,那么最后相当于执行
String sql = "select * from users"
直接曝露所有用户信息。更有甚者,可将语句变为
String sql = "select * from users;drop table users;"
将用户数据全部删除。
因此,需要使用PreparedStatement对象而不是用Statement对象来预编译SQL语句。主要有三点优势:
- PreparedStatement可以写动态参数化的查询
- PreparedStatement比 Statement 更快
- PreparedStatement可以防止SQL注入式攻击
使用mybatis框架动态参数使用'$'而不是'#'
反例:
<dynamic prepend="where">
<isParameterPresent>
<isNotEmpty prepend="and" property="onShelves">
p.onshelves=$onShelves$
</isNotEmpty>
</isParameterPresent>
</dynamic>
正例:
<dynamic prepend="where">
<isParameterPresent>
<isNotEmpty prepend="and" property="onShelves">
p.onshelves=#onShelves#
</isNotEmpty>
</isParameterPresent>
</dynamic>
'#'解析为一个 JDBC 预编译语句(prepared statement)的参数标记符。而'$'仅仅为一个纯碎的 string 替换,在动态 SQL 解析阶段将会进行变量替换。
注意点:
- 能使用 #{}的地方就用 #{}
- 表名作为变量时,必须使用 ${}
如何防止
- 永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和双"-"进行转换等。
- 永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。
- 可通过一些检查方法来进行安全测验。sql注入的检测方法一般采取辅助软件或网站平台来检测,软件一般采用sql注入检测工具jsky,网站平台就有亿思网站安全平台检测工具。