简单了解Mybatis如何实现SQL防注入

这篇文章主要介绍了简单了解Mybatis如何实现SQL防注入,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

Mybatis这个框架在日常开发中用的很多,比如面试中经常有一个问题:$和#的区别,它们的区别是使用#可以防止SQL注入,今天就来看一下它是如何实现SQL注入的。

什么是SQL注入

在讨论怎么实现之前,首先了解一下什么是SQL注入,我们有一个简单的查询操作:根据id查询一个用户信息。它的sql语句应该是这样:select * from user where id =。我们根据传入条件填入id进行查询。

如果正常操作,传入一个正常的id,比如说2,那么这条语句变成select * from user where id =2。这条语句是可以正常运行并且符合我们预期的。

但是如果传入的参数变成'' or 1=1,这时这条语句变成select * from user where id = '' or 1=1。让我们想一下这条语句的执行结果会是怎么?它会将我们用户表中所有的数据查询出来,显然这是一个大的错误。这就是SQL注入。

Mybatis如何防止SQL注入

在开头讲过,可以使用#来防止SQL注入,它的写法如下:

<select id="safeSelect" resultMap="testUser">
  SELECT * FROM user where id = #{id}
</select>

在mybatis中查询还有一个写法是使用$,它的写法如下:

<select id="unsafeSelect" resultMap="testUser">
  select * from user where id = ${id}
</select>

当我们在外部对这两个方法继续调用时,发现如果传入安全的参数时,两者结果并无不同,如果传入不安全的参数时,第一种使用#的方法查询不到结果(select * from user where id = '' or 1=1),但这个参数在第二种也就是$下会得到全部的结果。

并且如果我们将sql进行打印,会发现添加#时,向数据库执行的sql为:select * from user where id = ' \'\' or 1=1 ',它会在我们的参数外再加一层引号,在使用$时,它的执行sql是select * from user where id = '' or 1=1。

弃用$可以吗

我们使用#也能完成$的作用,并且使用$还有危险,那么我们以后不使用$不就行了吗。

并不是,它只是在我们这种场景下会有问题,但是在有一些动态查询的场景中还是有不可代替的作用的,比如,动态修改表名select * from ${table} where id = #{id}。我们就可以在返回信息一致的情况下进行动态的更改查询的表,这也是mybatis动态强大的地方。

如何实现SQL注入的,不用Mybatis怎么实现

其实Mybatis也是通过jdbc来进行数据库连接的,如果我们看一下jdbc的使用,就可以得到这个原因。

#使用了PreparedStatement来进行预处理,然后通过set的方式对占位符进行设置,而$则是通过Statement直接进行查询,当有参数时直接拼接进行查询。

所以说我们可以使用jdbc来实现SQL注入。

看一下这两个的代码:

public static void statement(Connection connection) {
 System.out.println("statement-----");
 String selectSql = "select * from user";
 // 相当于mybatis中使用$,拿到参数后直接拼接
 String unsafeSql = "select * from user where id = '' or 1=1;";
 Statement statement = null;
 try {
  statement = connection.createStatement();
 } catch (SQLException e) {
  e.printStackTrace();
 }
 try {
  ResultSet resultSet = statement.executeQuery(selectSql);
  print(resultSet);
 } catch (SQLException e) {
  e.printStackTrace();
 }
 System.out.println("---****---");
 try {
  ResultSet resultSet = statement.executeQuery(unsafeSql);
  print(resultSet);
 } catch (SQLException e) {
  e.printStackTrace();
 }
}

public static void preparedStatement(Connection connection) {
 System.out.println("preparedStatement-----");
 String selectSql = "select * from user;";
 //相当于mybatis中的#,先对要执行的sql进行预处理,设置占位符,然后设置参数
 String safeSql = "select * from user where id =?;";
 PreparedStatement preparedStatement = null;
 try {
  preparedStatement = connection.prepareStatement(selectSql);
  ResultSet resultSet = preparedStatement.executeQuery();
  print(resultSet);
 } catch (SQLException e) {
  e.printStackTrace();
 }
 System.out.println("---****---");
 try {
  preparedStatement = connection.prepareStatement(safeSql);
  preparedStatement.setString(1," '' or 1 = 1 ");
  ResultSet resultSet = preparedStatement.executeQuery();
  print(resultSet);
 } catch (SQLException e) {
  e.printStackTrace();
 }
}

public static void print(ResultSet resultSet) throws SQLException {
 while (resultSet.next()) {
  System.out.print(resultSet.getString(1) + ", ");
  System.out.print(resultSet.getString("name") + ", ");
  System.out.println(resultSet.getString(3));
 }
}

总结

  • Mybatis中使用#可以防止SQL注入,$并不能防止SQL注入
  • Mybatis实现SQL注入的原理是调用了jdbc中的PreparedStatement来进行预处理。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • MyBatisPlus 自定义sql语句的实现

    一.引言 Good Good Study,Day Day Up MP自带的条件构造器虽然很强大,有时候也避免不了写稍微复杂一点业务的sql,那么那么今天说说MP怎么自定义sql语句吧. 二.配置 自定义的sql当然是写在XML文件中的啦,那么首先来定义xml文件的位置,在yml配置文件如下 mybatis-plus: # 如果是放在src/main/java目录下 classpath:/com/*/*/mapper/*Mapper.xml # 如果是放在resource目录 classpath:

  • MyBatis动态Sql之if标签的用法详解

    最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 本篇博客主要讲解如何使用if标签生成动态的Sql,主要包含以下3个场景: 1.根据查询条件实现动态查询 2.根据参数值实现动态更新某些列 3.根据参数值实现动态插入某些列 1. 使用if标签实现动态查询 假设有这样1个需求:根据用户的输入条件来查询用户列表,如果输入了用户名,就根据用户名模糊查询,如果输入了邮箱,就根据邮箱精确查询,如果同时输入了

  • Mybatis模糊查询和动态sql语句的用法

    Mybatis 模糊查询和动态sql语句 模糊查询 对数据库最常用的操作就是查询了,但是如何使用Mybatis进行模糊查询呢?下面先看一个简单的模糊查询 <select id="select01" resultMap="BasicResultMap"> SELECT * FROM oa_employee WHERE emp_name LIKE #{asd} </select> 这是一条伪模糊查询, 因为没有实现真正的模糊 "%&qu

  • mybatis 实现 SQL 查询拦截修改详解

    前言 截器的一个作用就是我们可以拦截某些方法的调用,我们可以选择在这些被拦截的方法执行前后加上某些逻辑,也可以在执行这些被拦截的方法时执行自己的逻辑而不再执行被拦截的方法. Mybatis拦截器设计的一个初衷就是为了供用户在某些时候可以实现自己的逻辑而不必去动Mybatis固有的逻辑.比如我想针对所有的SQL执行某个固定的操作,针对SQL查询执行安全检查,或者记录相关SQL查询日志等等. Mybatis为我们提供了一个Interceptor接口,可以实现自定义的拦截器. public inter

  • mybatis动态sql之Map参数的讲解

    mybatis 动态sql之Map参数 Mapper文件: <mapper namespace="com.cn.shoje.oa.modules.logistics.dao.PurcDao"> <select id="findAll" parameterType="Map" resultType="Purchase"> select * from prod_purchase where 1=1 <

  • 结合mybatis-plus实现简单不需要写sql的多表查询

    项目地址: GITHUB (本地下载) java mybatis 多表查询 简介 实现简单的实体类操作多表,  首先你的项目是使用了mybatis-plus 才可以使用 设计说明 如何关联表? 找第一张表注解为 TableId (mybatis-plus 注解)的属性名, 到每二张表找同样的属性名, 如果没找到,反过来找,如果还没找到,挨个属性找.以此类推,实现关联的前提条件是 主从表的关联例名必须一样 // user 表 @TableId private Integer userId // a

  • spring boot配置MySQL数据库连接、Hikari连接池和Mybatis的简单配置方法

    此方法为极简配置,支持MySQL数据库多库连接.支持Hikari连接池.支持MyBatis(包括Dao类和xml文件位置的配置). 1.pom.xml中引入依赖: <!-- Begin of DB related --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId>

  • MyBatis执行动态SQL的方法

    大家基本上都知道如何使用 MyBatis 执行任意 SQL,使用方法很简单,例如在一个 XXMapper.xml 中: <select id="executeSql" resultType="map"> ${_parameter} </select> 你可以如下调用: sqlSession.selectList("executeSql", "select * from sysuser where enabled

  • Spring + mybatis + mysql使用事物的几种方法总结

    前言 本文主要记录下spring是如何支持事物的,以及在Spring结合mybatis时,可以怎么简单的实现数据库的事物功能,下面话不多说了,来一起看看详细的介绍吧. I. 前提 case1:两张表的的事物支持情况 首先准备两张表,一个user表,一个story表,结构如下 CREATE TABLE `user` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL DEFAULT '' COMM

  • 简单了解Mybatis如何实现SQL防注入

    这篇文章主要介绍了简单了解Mybatis如何实现SQL防注入,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Mybatis这个框架在日常开发中用的很多,比如面试中经常有一个问题:$和#的区别,它们的区别是使用#可以防止SQL注入,今天就来看一下它是如何实现SQL注入的. 什么是SQL注入 在讨论怎么实现之前,首先了解一下什么是SQL注入,我们有一个简单的查询操作:根据id查询一个用户信息.它的sql语句应该是这样:select * from u

  • php简单实现sql防注入的方法

    本文实例讲述了php简单实现sql防注入的方法.分享给大家供大家参考,具体如下: 这里没有太多的过滤,主要是针对php和mysql的组合. 一般性的防注入,只要使用php的 addslashes 函数就可以了. 以下是一段copy来的代码: PHP代码: $_POST = sql_injection($_POST); $_GET = sql_injection($_GET); function sql_injection($content) { if (!get_magic_quotes_gpc

  • 详解Mybatis框架SQL防注入指南

    前言 SQL注入漏洞作为WEB安全的最常见的漏洞之一,在java中随着预编译与各种ORM框架的使用,注入问题也越来越少.新手代码审计者往往对Java Web应用的多个框架组合而心生畏惧,不知如何下手,希望通过Mybatis框架使用不当导致的SQL注入问题为例,能够抛砖引玉给新手一些思路. 一.Mybatis的SQL注入 Mybatis的SQL语句可以基于注解的方式写在类方法上面,更多的是以xml的方式写到xml文件.Mybatis中SQL语句需要我们自己手动编写或者用generator自动生成.

  • php中addslashes函数与sql防注入

    本文实例讲述了php中addslashes函数与sql防注入.分享给大家供大家参考.具体分析如下: addslashes可会自动给单引号,双引号增加\\\\\\,这样我们就可以安全的把数据存入数据库中而不黑客利用,参数'a..z'界定所有大小写字母均被转义,代码如下: 复制代码 代码如下: echo addcslashes('foo[ ]','a..z'); //输出:foo[ ] $str="is your name o'reilly?"; //定义字符串,其中包括需要转义的字符 e

  • php SQL防注入代码集合

    SQL防注入代码一 复制代码 代码如下: <?php /** * 防sql注入 * @author: zhuyubing@gmail.com * */ /** * reject sql inject */ if (!function_exists (quote)) { function quote($var) { if (strlen($var)) { $var=!get_magic_quotes_gpc() ? $var : stripslashes($var); $var = str_rep

  • ASP SQL防注入的方法

    下面我们将要介绍另一种在ASP里防SQL注入攻击的方法,该方法不仅仅在ASP里适用,实际上可以在任何使用ADO对象模型与数据库交互的语言中,准确的说称之为基于ADO对象模型的防SQL注入的方法或许更恰当些.好了废话不说了,来看看代码 复制代码 代码如下: Dim conn,cmd,pra set conn=server.createobject("adodb.connection") conn.Open "----" '这里省略数据库连接字 set cmd=serv

  • 编写通用的asp防注入程序

    编写通用的asp防注入程序     选择自 ph4studio 的 Blog   关键字   编写通用的asp防注入程序  出处 sql注入被那些菜鸟级别的所谓黑客高手玩出了滋味,,发现现在大部分黑客入侵都是基于sql注入实现的  ,哎,,谁让这个入门容易呢,好了,,不说废话了,,现在我开始说如果编写通用的sql防注入程序  一般的http请求不外乎 get 和 post,所以只要我们在文件中过滤所有post或者get请求中的参数信息中  非法字符即可,所以我们实现http 请求信息过滤就可以判

  • mybatis注解动态sql注入map和list方式(防sql注入攻击)

    目录 网上的教程 我的教程(防sql注入攻击) 注入Map 注入List 封装foreach mybatis防止sql注入的循环map写法 网上的教程 配置xml 注解中写xml脚本@Select() 使用Java类中的Java方法拼写sql语句(不防sql注入攻击的纯字符串拼接) 我的教程(防sql注入攻击) 注入Map Mapper层代码 @Repository public interface ManageMapper { @SelectProvider(type = ManageProv

  • 结合Mybatis聊聊对SQL注入的见解

    目录 Mybatis聊聊对SQL注入的见解 1.sql注入是什么 2.sql注入实例 (1)特殊符号,如 ' 和 .等 (2)sql语句的注入 (3)通过sql语句的in和order by进行注入 3.mybatis框架下如何解决sql注入问题 (1)用#{param}替换所有的${param} (2)对用户输入的数据进行sql注入校验 (3)要对用户的权限进行区分 (4)更高级别的验证 一种常见的Mybatis的SQL注入 一.场景重现 二.代码展示 三.模拟请求&回应结果 四.小结一下 My

  • 简单实用的PHP防注入类实例

    本文实例讲述了简单实用的PHP防注入类.分享给大家供大家参考.具体如下: PHP防注入注意要过滤的信息基本是get,post,然后对于sql就是我们常用的查询,插入等等sql命令了,下面我给各位整理两个简单的例子,希望这些例子能给你网站带来安全. PHP防注入类代码如下: 复制代码 代码如下: <?php /**  * 参数处理类  * @author JasonWei  */ class Params {     public $get = array();       public $pos

随机推荐