JDBC防止SQL注入(菜鸟笔记)

    技术2022-05-20  56

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

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


    最新回复(0)