日期:2014-05-16  浏览次数:20378 次

JDBC中的SQL注入问题:

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 方法清除它为止。

在连接的缺省模式下(启用自动提交),当语句完成时将自动提交或还原该语句。

(完)

?