日期:2014-05-16 浏览次数:20378 次
JDBC中的SQL注入问题:
SQL注入是利用某些系统没有对用户输入数据进行充分的验证的情况下,用户输入了恶意的SQL命令,导致数据库完成了错误的命令,或者导致数据库崩溃的方法。
下面是一个实例:
String sql = "select * from ATable where name='" + name + "'"; state = conn.createStatement(); rs = state.executeQuery(sql); // 显示查询结果 while (rs.next()) { System.out.println(rs.getInt(1) + " " + rs.getString(2)); }
如果这里传进来的是? String name = "'1' or '1'='1'";
拼接出来的SQL语句中where语句后面的条件是(select * from ATable where name='1' or '1'='1')永远都是成立。这会使Statement出现不可预料的结果。
为了解决这个问题。我们可以使用PrepareStatement。对上面没有验证的语句进行验证。
Connection conn = DbUtils.getConnection(); PreparedStatement state = null; ResultSet rs = null; try { String sql = "select * from ATable where name=?"; state = conn.prepareStatement(sql); state.setString(1, name); rs = state.executeQuery(); // 显示查询结果 while (rs.next()) { System.out.println(rs.getInt(1) + " " + rs.getString(2)); } }
?
PreparedStatement继承了Statement,没有了SQL注入的问题。(preparedStatement进行了预编译。)
如果使用预编译语句.传入的任何内容就不会和原来的语句发生任何匹配的关系.
只要全使用预编译语句,你就用不着对传入的数据做任何过虑.
而如果使用普通的statement,就要对drop等做费尽心机的判断和过虑.
如上面的程序:state = conn.prepareStatement(sql);
state 对象包含语句"select * from ATable where name=?",它已发送给DBMS,并为执行作好了准备。
设定参数:state.setString(1, name);
一旦设置了给定语句的参数值,就可用它多次执行该语句,直到调用clearParameters 方法清除它为止。
在连接的缺省模式下(启用自动提交),当语句完成时将自动提交或还原该语句。
(完)
?