• SQL注入的问题&使用PreparedStatement对象防止SQL注入


    1.SQL注入的问题:sql存在漏洞,会被攻击导致数据泄露

    SQL注入是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
    在拼接SQL时,有一些sql的特殊关键字参与字符串的拼接,会造成一些安全性的问题

    package cn.company.jdbc;
    
    import cn.company.jdbc.utils.JdbcUtils;
    
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    public class SQL注入 {
        public static void main(String[] args) throws SQLException {
            login("kuangshen", "123456");  // 正常传参
            System.out.println("===========");
            login(" 'or '1=1", "123456");  // SQL注入,把所有的信息都盗取出来
        }
    
        // 登录业务
        public static void login(String username, String password) throws SQLException {
            Connection connection = null;
            Statement statement = null;
            ResultSet rs = null;
            try {
                connection = JdbcUtils.getConnection();
                statement = connection.createStatement();
                String sql = "select * from users where `name`='"+username+"'AND `password` ='"+password+"'";
                rs = statement.executeQuery(sql);
                while (rs.next()) {
                    System.out.println(rs.getObject("name"));
                    System.out.println(rs.getObject("password"));
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                JdbcUtils.releaseConnection(connection, statement, rs);
            }
        }
    }
    

     

     可以看到SQL注入能够把所有的信息盗取出来。

    2.解决SQL注入问题

    后期都会使用PreparedStatement来完成增删改查的所有操作

    使用PreparedStatement可以防止SQL注入,并且效率更高

    PreparedStatement防止SQL注入的本质,把传递进来的参数当做字符,假设其中存在转义字符,就直接忽略,比如说 会被直接转义

    预编译SQL,参数使用?作为占位符,需要在执行SQL的时候,给?赋值

    静态的SQL,之前的Statement用于执行静态SQL语句,所谓静态的,就是SQL语句是字符串拼接的方式,

    步骤:

    (1)导入驱动jar包

    (2)注册驱动(让程序知道是哪个驱动包)

    (3)获取数据库链接对象Connection

    (4)定义sql

    注意:SQL的参数使用?作为占位符,如:select * from user where username=? and password=?;

    (5)获取执行sql语句的对象,PreparedSatement  Connection.prepareStatement(String sql)

    (6)给?赋值:

      方法:使用setXxx(参数1,参数2),参数1表示?的位置编号,从1开始;参数2表示?的值

    (7)执行sql,接受返回结果,不需要传递SQL语句

    (7)处理结果

    (8)释放资源

    新增:

    package cn.company.jdbc;
    
    import cn.company.jdbc.utils.JdbcUtils;
    
    import java.sql.Connection;
    import java.util.Date;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    public class TestPreparedStatement {
        public static void main(String[] args) throws SQLException {
            Connection conn = null;
            PreparedStatement statement = null;
            try {
                conn = JdbcUtils.getConnection();
                // 使用占位符?代替参数
                String sql = "INSERT INTO users values(?,?,?,?,?)";
                statement = conn.prepareStatement(sql);
    
                // 手动给参数赋值
                statement.setString(1, String.valueOf(4));
                statement.setString(2, "qijiang");
                statement.setString(3, "123456");
                statement.setString(4,"243555777@qq.com" );
                // 注意点:sql.Date 数据库用的
                //        util.Date java用的  new Date().getTime()获取当前时间戳
                statement.setDate(5, new java.sql.Date(new Date().getTime()));
    
                // 执行sql
                int i = statement.executeUpdate();
                if (i > 0) {
                    System.out.println("插入成功!");
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                JdbcUtils.releaseConnection(conn, statement, null);
            }
        }
    }
    

      

     删除

    package cn.company.jdbc;
    
    import cn.company.jdbc.utils.JdbcUtils;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    public class TestPreparedStatementDelete {
        public static void main(String[] args) throws SQLException {
            Connection connection = null;
            PreparedStatement preparedStatement = null;
            try {
                connection = JdbcUtils.getConnection();
                String sql = "delete from users where id=?";
                // 预编译
                preparedStatement = connection.prepareStatement(sql);
                // 手动赋值
                preparedStatement.setInt(1, 4);  // id=4
                // 执行sql
                int i = preparedStatement.executeUpdate();
                if (i > 0) {
                    System.out.println("删除成功!");
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                JdbcUtils.releaseConnection(connection, preparedStatement, null);
            }
        }
    }
    

      更新

    package cn.company.jdbc;
    
    import cn.company.jdbc.utils.JdbcUtils;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    public class TestPreparedStatementUpdate {
        public static void main(String[] args) throws SQLException {
            Connection connection = null;
            PreparedStatement preparedStatement = null;
            try {
                connection = JdbcUtils.getConnection();
                String sql = "update users set name=? where id=?";
                // 预编译sql
                preparedStatement = connection.prepareStatement(sql);
    
                // 手动给参数赋值
                preparedStatement.setString(1, "Gump Yan");
                preparedStatement.setString(2, "3");
    
                // 执行sql
                int i = preparedStatement.executeUpdate();
                if (i > 0) {
                    System.out.println("修改成功!");
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                JdbcUtils.releaseConnection(connection, preparedStatement, null);
            }
        }
    }
    

      

     查询

    package cn.company.jdbc;
    
    import cn.company.jdbc.utils.JdbcUtils;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    public class TestPreparedStatementQuery {
        public static void main(String[] args) throws SQLException {
            login("lisi", "123456");
            // login(" 'or '1=1","123456");  // SQL注入
        }
    
        private static void login(String username, String password) throws SQLException {
            Connection connection = null;
            PreparedStatement preparedStatement = null;
            ResultSet rs = null;
            try {
                connection = JdbcUtils.getConnection();
                String sql = "select * from users where `name`=? and `password`=?";
                preparedStatement = connection.prepareStatement(sql);
                preparedStatement.setString(1, username);
                preparedStatement.setString(2, password);
                rs = preparedStatement.executeQuery();
                while (rs.next()) {
                    System.out.println(rs.getObject("name"));
                    System.out.println(rs.getObject("password"));
                    System.out.println("===============");
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                JdbcUtils.releaseConnection(connection, preparedStatement, rs);
            }
        }
    }
    

      

  • 相关阅读:
    Python基础(14)_python模块之configparser模块、suprocess
    Python基础(13)_python模块之re模块(正则表达式)
    Python基础(12)_python模块之sys模块、logging模块、序列化json模块、pickle模块、shelve模块
    Python基础(11)_python模块之time模块、rando模块、hashlib、os模块
    Python基础(10)_内置函数、匿名函数、递归
    python中内建函数isinstance的用法
    Python基础(9)_生成器(yield表达式形式)、面向过程编程
    Python基础(8)_迭代器、生成器、列表解析
    Python基础(7)_闭包函数、装饰器
    Python基础(6)_函数
  • 原文地址:https://www.cnblogs.com/GumpYan/p/14069516.html
Copyright © 2020-2023  润新知