• jdbc之防sql注入攻击


    1、SQL注入攻击:
         由于dao中执行的SQL语句是拼接出来的,其中有一部分内容是由用户从客户端传入,所以当用户传入的数据中包含sql关键字时,就有可能通过这些关键字改变sql语句的语义,从而执行一些特殊的操作,这样的攻击方式就叫做sql注入攻击
      
        PreparedStatement利用预编译的机制将sql语句的主干和参数分别传输给数据库服务器,从而使数据库分辨的出哪些是sql语句的主干哪些是参数,这样一来即使参数中带了sql的关键字,数据库服务器也仅仅将他当作参数值使用,关键字不会起作用,从而从原理上防止了sql注入的问题

      PreparedStatement主要有如下的三个优点:
       1.可以防止sql注入
       2.由于使用了预编译机制,执行的效率要高于Statement
       3.sql语句使用?形式替代参数,然后再用方法设置?的值,比起拼接字符串,代码更加优雅.

      PreparedStatement 与Statment比较

                       1)语法不同:PreparedStatement可以使用预编译的sql,而Statment只能使用静态的sql

                       2)效率不同: PreparedStatement可以使用sql缓存区,效率比Statment高

                       3)安全性不同: PreparedStatement可以有效防止sql注入,而Statment不能防止sql注入。

     

    /**
     * PreparedStatement執行sql語句
     * 
     *
     */
    public class Demo1 {
    
        /**
         * 增加
         */
        @Test
        public void testInsert() {
            Connection conn = null;
            PreparedStatement stmt = null;
            try {
                //1.获取连接
                conn = JdbcUtil.getConnection();
                
                //2.准备预编译的sql
                String sql = "INSERT INTO student(NAME,gender) VALUES(?,?)"; //?表示一个参数的占位符
                
                //3.执行预编译sql语句(检查语法)
                stmt = conn.prepareStatement(sql);
                
                //4.设置参数值
                /**
                 * 参数一: 参数位置  从1开始
                 */
                stmt.setString(1, "李四");
                stmt.setString(2, "男");
                
                //5.发送参数,执行sql
                int count = stmt.executeUpdate();
                
                System.out.println("影响了"+count+"行");
                
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            } finally {
                JdbcUtil.close(conn, stmt);
            }
        }
        
        /**
         * 修改
         */
        @Test
        public void testUpdate() {
            Connection conn = null;
            PreparedStatement stmt = null;
            try {
                //1.获取连接
                conn = JdbcUtil.getConnection();
                
                //2.准备预编译的sql
                String sql = "UPDATE student SET NAME=? WHERE id=?"; //?表示一个参数的占位符
                
                //3.执行预编译sql语句(检查语法)
                stmt = conn.prepareStatement(sql);
                
                //4.设置参数值
                /**
                 * 参数一: 参数位置  从1开始
                 */
                stmt.setString(1, "王五");
                stmt.setInt(2, 9);
                
                //5.发送参数,执行sql
                int count = stmt.executeUpdate();
                
                System.out.println("影响了"+count+"行");
                
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            } finally {
                JdbcUtil.close(conn, stmt);
            }
        }
        
        /**
         * 删除
         */
        @Test
        public void testDelete() {
            Connection conn = null;
            PreparedStatement stmt = null;
            try {
                //1.获取连接
                conn = JdbcUtil.getConnection();
                
                //2.准备预编译的sql
                String sql = "DELETE FROM student WHERE id=?"; //?表示一个参数的占位符
                
                //3.执行预编译sql语句(检查语法)
                stmt = conn.prepareStatement(sql);
                
                //4.设置参数值
                /**
                 * 参数一: 参数位置  从1开始
                 */
                stmt.setInt(1, 9);
                
                //5.发送参数,执行sql
                int count = stmt.executeUpdate();
                
                System.out.println("影响了"+count+"行");
                
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            } finally {
                JdbcUtil.close(conn, stmt);
            }
        }
        
        /**
         * 查询
         */
        @Test
        public void testQuery() {
            Connection conn = null;
            PreparedStatement stmt = null;
            ResultSet rs = null;
            try {
                //1.获取连接
                conn = JdbcUtil.getConnection();
                
                //2.准备预编译的sql
                String sql = "SELECT * FROM student"; 
                
                //3.预编译
                stmt = conn.prepareStatement(sql);
                
                //4.执行sql
                rs = stmt.executeQuery();
                
                //5.遍历rs
                while(rs.next()){
                    int id = rs.getInt("id");
                    String name = rs.getString("name");
                    String gender = rs.getString("gender");
                    System.out.println(id+","+name+","+gender);
                }
                
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            } finally {
                //关闭资源
                JdbcUtil.close(conn,stmt,rs);
            }
        }
    }

    eg:模拟登陆

    /**
     * 模拟用户登录效果
     * 
     *
     */
    public class Demo2 {
        //模拟用户输入
        //private String name = "ericdfdfdfddfd' OR 1=1 -- ";
        private String name = "eric";
        //private String password = "123456dfdfddfdf";
        private String password = "123456";
    
        /**
         * Statment存在sql被注入的风险
         */
        @Test
        public void testByStatement(){
            Connection conn = null;
            Statement stmt = null;
            ResultSet rs = null;
            try {
                //获取连接
                conn = JdbcUtil.getConnection();
                
                //创建Statment
                stmt = conn.createStatement();
                
                //准备sql
                String sql = "SELECT * FROM users WHERE NAME='"+name+"' AND PASSWORD='"+password+"'";
                
                //执行sql
                rs = stmt.executeQuery(sql);
                
                if(rs.next()){
                    //登录成功
                    System.out.println("登录成功");
                }else{
                    System.out.println("登录失败");
                }
                
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            } finally {
                JdbcUtil.close(conn, stmt ,rs);
            }
            
        }
        
        /**
         * PreparedStatement可以有效地防止sql被注入
         */
        @Test
        public void testByPreparedStatement(){
            Connection conn = null;
            PreparedStatement stmt = null;
            ResultSet rs = null;
            try {
                //获取连接
                conn = JdbcUtil.getConnection();
                
                String sql = "SELECT * FROM users WHERE NAME=? AND PASSWORD=?";
                
                //预编译
                stmt = conn.prepareStatement(sql);
                
                //设置参数
                stmt.setString(1, name);
                stmt.setString(2, password);
                
                //执行sql
                rs = stmt.executeQuery();
                
                if(rs.next()){
                    //登录成功
                    System.out.println("登录成功");
                }else{
                    System.out.println("登录失败");
                }
                
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            } finally {
                JdbcUtil.close(conn, stmt ,rs);
            }
            
        }
    }
  • 相关阅读:
    昨晚睡不着觉,测这周运气
    老大让我看baidu他们的查公交是怎么做的,我就看了
    破逼Json,该死的Json库,操了
    我真的好累,实在不知道该怎么办了
    今晚刚回家,给人算了一卦运气
    bzoj4590[Shoi2015]自动刷题机
    bzoj4552[Tjoi2016&Heoi2016]排序
    bzoj3155Preprefix sum
    bzoj2463[中山市选2009]谁能赢呢?
    bzoj3668[Noi2014]起床困难综合症
  • 原文地址:https://www.cnblogs.com/flei/p/6727520.html
Copyright © 2020-2023  润新知