首页 > 数据库 >聊聊SQL注入

聊聊SQL注入

时间:2022-09-30 19:22:05浏览次数:51  
标签:uid 参数 聊聊 SQL where select 注入

SQL注入问题

  • 概述:

    • 首先SQL注入是一个非常危险的操作,很可能被一些不怀好意的人钻空导致我们系统出现异常等状况,比如数据库遭到破坏或被入侵。
  • 原因:使用JDBC的Statement语句添加SQL语句

    • 由于我们的JDBC在对数据库进行操作时,需要客户端传入一些参数。我们在日常中的处理是将字符串参数作为SQL语句进行拼接,但是加入客户端传入SQL语句关键字恶意篡改SQL语句就会改变服务端SQL语义发生系统异常。严重时就会导致系统和数据库破坏,这时的攻击方式就叫SQL注入了。

    • 实例:模拟登录请求传入用户id和密码参数,使用字符串拼接导致的SQL注入。

      • 拼接SQL语句,就会出现SQL注入的安全问题,拼接代码如下:

        String sql = "select * from user where username='" + uid + "' and password='" + passwd + "'";
        
      • 若此时传入参数如下:永真式 或 封号结束注释后面条件验证(只能说人的脑洞真大哈哈)

        params.put("uid", "malongfei");
        params.put("passwd", "111' or '1' = '1"); 
        // 或者
        params.put("uid", "malongfei'; -- ")
        // 或者
        params.put("uid", "malongfei'; # ")
        
      • 此时JDBC还没意识到安全问题,依旧将以上参数拼接到我们的SQL原语中,如下:

        select * from user where uid = 'malongfei' and passwd = '111' or '1' = '1';
        select * from user where uid = 'malongfei'; -- ' and passwd = '111' or '1' = '1';
        select * from user where uid = 'malongfei'; # ' and passwd = '111' or '1' = '1';
        
  • 预防SQL注入:使用PreparedStatement代替Statement可以有效防止SQL注入。

    • PreparedStatement利用预编译的机制将sql语句的主干和参数分别传输给数据库服务器,这样即使参数中携带数据库关键字,也不能作为SQL中真正的关键字而起作用。
    // 后端登录验证密码接口的SQL语句
    select * from user where uid = ? and passwd = ?;
    
    • 设置黑名单也可提前预防,单纯针对于用户输入中含有SQL关键字的拦截方法,比如在注册账号时,用户名和密码中不能含有SQL语句关键字;
    • 或者说在进行SQL拼接时加入逻辑处理,对传入参数含有SQL关键字的进行报输入异常。
  • PreparedStatementStatment 区别:

    1. 语法不同:PreparedStatement 使用预编译的sql,而 Statment 使用静态的sql
    2. 效率不同: PreparedStatement 具有 sql缓存区,效率比 Statment 高
    3. 安全性不同:PreparedStatement 可以有效防止sql注入,而 Statment 不能

Mybatis对SQL注入的预防处理

  • 出现SQL注入问题的原因和上面一样,都是由于拼接SQL导致的,只不过方式不同。

    • Mybatis接收参数处理有两种语法:#{}${}#使用预编译,$使用拼接SQL方式。
    • 这里需要注意的是:使用#运算符,Mybatis会将传入的参数当成一个字符串,在进行变量替换时会加上引号!
  • mybatis 出现SQL注入实例:

    • 模糊查询时,如下实例:

      • 采用 #{} 的话程序会报异常。最后替换成 like "'name'"

        select * from users where name like '%#{name}%'
        
      • 常人看了既然#{}报错那么我用${},正中SQL注入的下怀,这个时候倘若我们的服务端 Java 代码没有对传入参数进行拦截处理,SQL注入条件满足!

        select * from users where name like '%${name}%'
        
      • 正确SQL写法,需要使用 concat函数 来进行连接参数(concat为mysql函数,连接参数产生字符串)

        select * from users where name like concat('%',#{name}, '%')
        
  • 补充:

    • in 之后的多个参数在mybatis中也不能采用 #{} 或者 ${} ,需要使用动态SQL语法中 foreach 循环遍历

      select * from users where id in
      <foreach collection="ids" item="item" open="("separatosr="," close=")">
      	#{item}
      </foreach>
      
    • order by 之后也不能使用 #{},他也会将字段改为字符串形式,加上引号后就不能正常排序,所以我们需要考虑 ${} 的方式,但是在后台代码中一定要进行数据参数的校验等手段,防止SQL注入.

标签:uid,参数,聊聊,SQL,where,select,注入
From: https://www.cnblogs.com/malongfeistudy/p/16745900.html

相关文章

  • MySQL Workbench 创建用户
    创建本机用户    选择权限(增删改查)6个  创建新用户编辑窗口   ......
  • 【MYSQL】【基础知识】【MySQL的基本使用】
    【MYSQL】【基础知识】【MySQL的基本使用】本文基于5.7.20版本mysql个人知识总结,或有疏漏错误,仅供参考。第一章和第二章可忽略不看一、MySQL服务器的安装与使用以下c......
  • SpringBoot+Vue社区团购系统 团购商城管理系统 商城购物系统Java Vue MySQL数据库 远
    ......
  • 学习笔记-SQL注入(SQLI-LABS第一关)
    初学者掌握手工注入的过程:(1)判断是否存在注入点//(URL,POST表单,HTTP头部字段......)(2)判断字段长度(字段数)//(有可能保存在后台数据库某一个表当中......
  • 系统库- SQL Server隐藏系统库Resource探究
    概述对于许多熟悉SQLServer的人来说,系统数据库只与四个数据库相关联,它们分别是master、model、msdb、tempdb。即使在SQLServerManagementStudio(SSMS)中,当......
  • SQL之高级数据过滤
    1、组合WHERE子句1.1、AND操作符1select2col_name3from4table_name5where6col_name='str'7and8col_name2='str';1.2、OR操作符......
  • 如何通过执行SQL为低代码项目提速?
    见多了SQL为代码开发提速,那么当低代码遇到SQL会擦出怎样的火花呢?本文将低代码和SQL结合进行介绍,让大家了解如何通过执行SQL为低代码项目提速。背景自从计算机诞生的一刻起......
  • sqlserver 之 CROSS apply
    CROSSapply作用:两张表直接连接,不需要任何的关联条件,产生的结果就是这两张表的笛卡儿集。相当于:select*fromtableA,tableB。 使用场景:如果查询结果集需要用到表值函......
  • r2d2-postgresql
    externcrater2d2;usestd::{thread,io::Read};user2d2_postgres::{postgres::{NoTls,GenericClient,SimpleQueryRow,SimpleQueryMessage},PostgresConnectionM......
  • 如何通过执行SQL为低代码项目提速?
    见多了SQL为代码开发提速,那么当低代码遇到SQL会擦出怎样的火花呢?本文将低代码和SQL结合进行介绍,让大家了解如何通过执行SQL为低代码项目提速。背景自从计算机诞生的一刻......