MyBatis最佳实践:SQL注入问题

什么是 SQL 注入:

  1. SQL 注入是一种注入攻击,可以执行恶意 SQL 语句,它将任意 SQL 代码插入数据库查询,使攻击者能够完全控制 WEB 应用程序后面的数据库服务器,攻击者可以使用 SQL 注入漏洞绕过程序安全措施
  2. 可以绕过网页或 WEB 应用程序的身份验证和授权,并检索中整个 SQL 数据库的内容
  3. 还可以使用 SQL 注入来添加、修改和删除数据库中的记录
  4. 简单来说:
    1. SQL 注入是一种将 SQL 代码添加到输入参数中,传递到 SQL服务器解析并执行的一种攻击手法,传入参数未经过过滤,直接拼接到 SQL 语句中,解析执行,达到预先之外的行为
  5. SQL注入案例:
    name = 'addss' and password = 1' or '1' = '1

SQL注入解决:

  1. JDBC解决:
    1. 把 SQL 语句中需要传参的位置用 ?占位符给替换
    2. 更改 Statement 对象为 PreparedStatement对象:
      //传入参数地方用占位符 ? 替换
      select * from student where name = ? and password = ?
      
      //未改动前语句: Statement statement = (Statement) connection.createStatement();
       //更改 Statement 对象为 PreparedStatement 
       //获取对象并编译sql      
      PreparedStatement statement = (PreparedStatement) connection.prepareStatement(sql);
      //给占位符赋值
      statement.setString(1, name);
      statement.setString(1, password);
    3. 解决方式:
      1. 使用 PreparedStatement 对象是先将 SQL 语句的骨架发送给服务器编译并确定下来,编译之后 SQL 语句的骨架和语义就不会再被改变了,再将 SQL 语句中的参数发送给服务器
      2. 即使参数中再包含 SQL 关键字或者特殊符号,也不会导致 SQL 语句的骨架或语义被改变,只会被当作普通的文本来处理
    4. 解决步骤:
      1. 使用 PreparedStatement 对象代替 Statement 对象传输 SQL 语句骨架,并返回一个 PreparedStatment 对象
        PreparedStatement ops = oCn.preparedStatemnt(sql);
        //说明:
            一个 SQL 语句骨架指的是使用 ? (占位符) 代替自定义变量后的 SQL 语句
                示例:select * from user where name = ? and password = ?;
            该方法使用一个 PreparedStatement 对象值对应一条 SQL 语句骨架,想要使用其他 SQL 语句骨架就得重新创建一个该类的对象
            
      2. 使用 PreparedStatement 的类方法 setBaseType(占位符序号,变量名);构造实参,填充占位符
        1. SQL 骨架中有多少个 ?就得使用该类方法构造多少个实参
        2. 该类方法第一个实参指的是占位符的服啊后,序号是从 1 开始的,区别与下标
        3. 构造的实参必须与占位符的序号 一 一 对应
        4. 方法名中的 BaseType 指的是不同类型的数据要使用对应类型的 set 方法,如类型 int 数据,则使用 setInt 方法构造实参
      3. 将填充完的 SQL 语句传输给数据库:
        oPs.executeQurey() 或 oPs.executeUpdate() 方法传输构造好的 SQL 语句
    5. 优点:
      1. 使用 PreparedStatement 对象可以防止 SQL 注入攻击
      2. 而且通过方法设置参数更加的方便且不易出错
      3. 还可以从某方面提高程序执行的效率
  2.  #{} 和 $ value} 符号:
    1. ${value}:数据拼接,在本地 SQL 语句进行拼接(会有 SQL 注入问题)
    2. #{}:占位符 ==> 被编译成占位符  ?
    3. 两者的选择:
      1. 能用 #{} 就用 #{},尽量少用 ${}
      2. 当数据作为参数,或者 order by 排序时用 ${}
      3. 传参时参数使用  @Param 注解,
      4. 正确的将参数传入 SQL 语句中,一般通过 #{} 的方式,${} 会有 SQL 注入的问题
    4. 原理:
      1. MyBatis 的 #{} 之所以能够预防 SQL 注入是因为底层使用了 PreparedStatment 类 setString() 方法来设置参数
      2. 此方法会获取参数传递过来的每个字符,然后进行循环对比,如果发现有敏感字符(如:单引号、双引号等),则会在上面加一个 '/' 代表转义符号,让其变成一个普通的字符串,不参与 SQL 语句的生成,达到预防 SQL 注入的效果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值