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注入.

聊聊SQL注入的更多相关文章

  1. 【转载】以Java的视角来聊聊SQL注入

    以Java的视角来聊聊SQL注入 原创 2017-08-08 javatiku Java面试那些事儿 在大二就接触过sql注入,之前一直在学习windows逆向技术,认为web安全以后不是自己的从业方 ...

  2. 重新学习MySQL数据库11:以Java的视角来聊聊SQL注入

    本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...

  3. 好久没考虑过的 sql 注入

    很多年没考虑 sql 注入了,毕业以后 使用mybatis #{ 参数的 语法 },这个 语法已经 做了防止 sql 注入的处理 . 看到同事写的 ${ 参数 },突然 想到这个问题 . 下面聊聊 s ...

  4. Youke365_2_4 一处Sql注入漏洞以及一处任意文件删除

    本文作者:X_Al3r Prat 0 自白 每一天都是新的一天.没啥吐槽的,步入正题 /system/category.php 文件一处Sql注入## 80-87行代码         $root_i ...

  5. 个人网站对xss跨站脚本攻击(重点是富文本编辑器情况)和sql注入攻击的防范

    昨天本博客受到了xss跨站脚本注入攻击,3分钟攻陷--其实攻击者进攻的手法很简单,没啥技术含量.只能感叹自己之前竟然完全没防范. 这是数据库里留下的一些记录.最后那人弄了一个无限循环弹出框的脚本,估计 ...

  6. Web安全相关(五):SQL注入(SQL Injection)

    简介 SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有细致地过滤用户输入的数据 ...

  7. 从c#角度看万能密码SQL注入漏洞

    以前学习渗透时,虽然也玩过万能密码SQL注入漏洞登陆网站后台,但仅仅会用,并不理解其原理. 今天学习c#数据库这一块,正好学到了这方面的知识,才明白原来是怎么回事. 众所周知的万能密码SQL注入漏洞, ...

  8. 浅谈SQL注入风险 - 一个Login拿下Server

    前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...

  9. 揭开SQL注入的神秘面纱PPT分享

        SQL注入是一个老生常谈但又经常会出现的问题.该课程是我在公司内部培训的课程,现在分享出来,希望对大家有帮助.     点击这里下载.

随机推荐

  1. Netty-ProtobufVarint32

    效果 ProtobufVarint32LengthFieldPrepender编码器用于在数据最前面添加Varint32,表示数据长度 ProtobufVarint32FrameDecoder是相对应 ...

  2. ASP.NET Core 6框架揭秘实例演示[29]:搭建文件服务器

    通过HTTP请求获取的Web资源很多都来源于存储在服务器磁盘上的静态文件.对于ASP.NET应用来说,如果将静态文件存储到约定的目录下,绝大部分文件类型都是可以通过Web的形式对外发布的." ...

  3. Java学习第五周

    这周学习了异常与多线程,线程使用 Exception异常的分类: 1.编译时异常:继承自Exception的异常或者其子类,编译阶段就会报错 2.运行时异常:继承自RuntimeException的异 ...

  4. YII事件EVENT示例

    模型中/** * 在初始化时进行事件绑定 */ public function init() { $this->on(self::EVENT_HELLO,[$this,'sendMail']); ...

  5. Java SE 9 多版本兼容 JAR 包示例

    Java SE 9 多版本兼容 JAR 包示例 作者:Grey 原文地址:Java SE 9 多版本兼容 JAR 包示例 说明 Java 9 版本中增强了Jar 包多版本字节码文件格式支持,也就是说在 ...

  6. CSS 选择器(二):子代选择器(>)

    后代选择器 后代选择器选择的范围广,范围是当前节点的所有子节点,包括其直接子节点. <div id="app"> <div>items-1 <div& ...

  7. 一文了解.Net的CLR、GC内存管理

    一文了解.Net的CLR.GC内存管理 微软官方文档对内存管理和CLR的概述 什么是托管代码? 托管代码就是执行过程交由运行时管理的代码. 在这种情况下,相关的运行时称为公共语言运行时 (CLR),不 ...

  8. 1.5_HTML基础标签实战演练

    基本的 HTML 标签 HTML 标题 HTML 标题(Heading)是通过 <h1> - <h6> 等标签进行定义的. <h1>This is a headin ...

  9. 【SWIFT】从零开始的SWIFT语言学习笔记-2:简单值、数组与字典

    1.0.3 简单值.数组与字典 知识点: 使用var创建变量 var myVariable = 65 myVariable = myVariable + 1 使用let创建常量 let myConst ...

  10. 【unity游戏入门】2 使用代码编写Hello Unity游戏

    作者 罗芭Remoo 2021年9月24日 第一章.许可证的安装 下载好Unity之后,我们还需要一个前置操作才可以进入Unity引擎----许可证. 当然不用担心,Unity是一个开放的引擎,一切以 ...