mybatis 学习笔记(二):mybatis SQL注入问题

SQL 注入攻击

首先了解下概念,什么叫SQL 注入:

SQL注入攻击,简称SQL攻击或注入攻击,是发生于应用程序之数据库层的安全漏洞。简而言之,是在输入的字符串之中注入SQL指令,在设计不良的程序当中忽略了检查,那么这些注入进去的指令就会被数据库服务器误认为是正常的SQL指令而运行,因此遭到破坏或是入侵。

最常见的就是我们在应用程序中使用字符串联结方式组合 SQL 指令,有心之人就会写一些特殊的符号,恶意篡改原本的 SQL 语法的作用,达到注入攻击的目的。

举个栗子:

比如验证用户登录需要 username 和 password,编写的 SQL 语句如下:

select * from user where (name = '"+ username +"') and (pw = '"+ password +"');

username 和 password 字段被恶意填入

username = "1' OR '1'='1";

password = "1' OR '1'='1";

将导致原本的 SQL 字符串被填为:

select * from user where (name = '1' or '1'='1') and (pw = '1' or '1'='1');

实际上运行的 SQL 语句将变成:

select * from user;

也就是不再需要 username 和 password 账密即达到登录的目的,结果不言而喻。

mybatis 解决 SQL 注入问题

我们使用 mybatis 编写 SQL 语句时,难免会使用模糊查询的方法,mybatis 提供了两种方式 #{}${}

  • #{value} 在预处理时,会把参数部分用一个占位符 ? 替代,其中 value 表示接受输入参数的名称。能有效解决 SQL 注入问题
  • ${} 表示使用拼接字符串,将接受到参数的内容不加任何修饰符拼接在 SQL 中,使用${}拼接 sql,将引起 SQL 注入问题。

举个栗子:

1 查询数据库 sample 表 user 中的记录,我们故意使用特殊符号,看能否引起 SQL 注入。使用 mybatis 在 mapper.xml 配置文件中编写 SQL 语句,我们先采用拼接字符串形式,看看结果如何:

 <select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">
<!-- 拼接 MySQL,引起 SQL 注入 -->
SELECT * FROM user WHERE username LIKE '%${value}%'
</select>

注意在配置文件中编写 SQL 语句时,后边不需要加分号。

调用配置文件,编写测试文件,查询数据库内容,采用特殊符号,引起 SQL 注入:

    @Test
public void testFindUserByName() throws Exception{ SqlSession sqlSession=sqlSessionFactory.openSession(); //创建UserMapper代理对象
UserMapper userMapper=sqlSession.getMapper(UserMapper.class); //调用userMapper的方法
List<User> list=userMapper.findUserByName("' or '1'='1"); sqlSession.close(); System.out.println(list);
}
}

运行结果如下图所示:

可以看到执行语句其实变为了

select * from user

将user 表中的全部记录打印出来了。发生了 SQL 注入。

2 如果将配置文件中的 SQL 语句改成 #{} 形式,可避免 SQL 注入。

 <select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">
<!-- 使用 SQL concat 语句,拼接字符串,防止 SQL 注入 -->
SELECT * FROM USER WHERE username LIKE CONCAT('%',#{value},'%' )
</select>

再次运行测试程序,控制台输出如下:

可以看到程序中参数部分用 ? 替代了,很好地解决了 SQL 语句的问题,防止了 SQL 注入。查询结果将为空。

mybatis 学习笔记(二):mybatis SQL注入问题的更多相关文章

  1. Mybatis学习笔记(二) —— mybatis入门程序

    一.mybatis下载 mybaits的代码由github.com管理,下载地址:https://github.com/mybatis/mybatis-3/releases 下载完后的目录结构: 二. ...

  2. MyBatis学习笔记二:MyBatis生产中使用环境搭建

    这里是在上一个环境的基础上修改的,这里就不在给出所有的配置,只给出哪里修改的配置 1.修改POJO对象为注解方式 2.创建Dao层接口 package com.orange.dao; import c ...

  3. MyBatis学习 之 二、SQL语句映射文件(2)增删改查、参数、缓存

    目录(?)[-] 二SQL语句映射文件2增删改查参数缓存 select insert updatedelete sql parameters 基本类型参数 Java实体类型参数 Map参数 多参数的实 ...

  4. MyBatis学习 之 二、SQL语句映射文件(1)resultMap

    目录(?)[-] 二SQL语句映射文件1resultMap resultMap idresult constructor association联合 使用select实现联合 使用resultMap实 ...

  5. MyBatis:学习笔记(4)——动态SQL

    MyBatis:学习笔记(4)——动态SQL

  6. Mybatis学习笔记二

    本篇内容,紧接上一篇内容Mybatis学习笔记一 输入映射和输出映射 传递简单类型和pojo类型上篇已介绍过,下面介绍一下包装类型. 传递pojo包装对象 开发中通过可以使用pojo传递查询条件.查询 ...

  7. mybatis学习笔记(二)-- 使用mybatisUtil工具类体验基于xml和注解实现

    项目结构  基础入门可参考:mybatis学习笔记(一)-- 简单入门(附测试Demo详细过程) 开始体验 1.新建项目,新建类MybatisUtil.java,路径:src/util/Mybatis ...

  8. MyBatis学习笔记(二)——使用MyBatis对表执行CRUD操作

    转自孤傲苍狼的博客:http://www.cnblogs.com/xdp-gacl/p/4262895.html 上一篇博文MyBatis学习总结(一)——MyBatis快速入门中我们讲了如何使用My ...

  9. MyBatis学习笔记(二) 关联关系

    首先给大家推荐几个网页: http://blog.csdn.net/isea533/article/category/2092001 没事看看 - MyBatis工具:www.mybatis.tk h ...

  10. Mybatis学习笔记14 - 动态sql之foreach标签

    一.查询给定集合中员工id对应的所有员工信息 示例代码: 接口定义: package com.mybatis.dao; import com.mybatis.bean.Employee; import ...

随机推荐

  1. oracle中,约束、表名、Index等的名称长度限制最大只能30个字符

    oracle中,约束.表名.Index等的名称长度限制最大只能30个字符

  2. Spring AOP面向切面编程详解

    前言 AOP即面向切面编程,是一种编程思想,OOP的延续.在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等等.在阅读本文前希望您已经对Spring有一定的了解 注:在能对代码进行添 ...

  3. LinqHelper连接数据库配置

    LinqHelper连接数据库配置/// <summary> /// Linq通用数据访问类 /// 指定TDataBase来代替后面要使用的数据上下文(指代) /// where:说明指 ...

  4. ffmpeg相关时间概念

    v_rescale_q用于计算Packet的PTS.av_rescale_q的返回值是一个很大的整数,且每次计算的结果间隔很大. 不同于avcodec_encode_video改变AVCodecCon ...

  5. USACO2.1.3 三值排序

      Description 排序是一种很频繁的计算任务.现在考虑最多只有三值的排序问题.一个实际的例子是,当我们给某项竞赛的优胜者按金银铜牌序的时候. 在这个任务中可能的值只有三种1,2和3.我们用交 ...

  6. random和os模块

    一.random模块 常用方法如下: #-*- coding:utf-8 -*- import random print(random.randint(1,100)) # 获取一个范围内的随机数,包含 ...

  7. Markdown使用简单示例(每一个使用对应一个实际的markdown语法)

    1.标题示例:通过"#"数量表示几级标题.(一共只有1~6级标题,1级标题字体最大) 标题一 #标题一 标题二 #标题二 标题三 ###标题三 标题四 ####标题四 标题五 ## ...

  8. window7 和ubuntu 双系统时 ubuntu不能引导怎么办?

    假如你的Ubuntu的 / 分区是sda9,又假如 /boot分区是 sda6,在终端下输入sudo -imount /dev/sda7 /mntmount /dev/sda6 /mnt/boot ( ...

  9. 数据库sql 开窗函数

    --本文采用Oracle数据库测试,前4个查询为一组,后2个查询为一组,每组前面的查询是为了推出最后的查询 --创建表,为了简化处理,字段类型都采用varcharcreate table tb_sc( ...

  10. ROS 不能安装 Ros Packages

    我的linux版本是16.04,安装的是kinetic 1. E: Some index files failed to download. They have been ignored, or ol ...