mybatis的sql中使用$会出现sql注入示例:

模拟简单登录场景:

页面代码:

function login(){
//sql注入
var user = {
username : "'李雪雷3' or 1=1",
password : "'ab0715'",
}
$.ajax({
url: '/api/test/login.json',
type: "POST",
data: JSON.stringify(user),//将对象序列化成JSON字符串
dataType: "json",
contentType : 'application/json;charset=utf-8', //设置请求头信息
async: false,
success: function (result) {
debugger;
$("#dis").html(result.data);
},
error: function (xhr, ajaxOptions, thrownError) {
debugger;
alert("出错了");
}
})
}
<input type="button" onclick="login()" value="登录" name="sunmitBtn">

controller:

@RequestMapping("/login")
@ResponseBody
public BaseResponse login(HttpServletRequest request, HttpServletResponse response, @RequestBody UserParam userParam){
try{
User user = userService.selectByCon(userParam);
if(user != null){
return BaseResponse.successCustom().setData("登录成功").build();
}
return BaseResponse.successCustom().setData("登录失败").build();
//return BaseResponse.successCustom().setData(returnVal).build();
}catch (Exception e){
e.printStackTrace();
return BaseResponse.failedCustom("系统异常").build();
}
}

service接口:

User selectByCon(UserParam userParam);

service实现类:

@Override
public User selectByCon(UserParam userParam) {
User user = userMapper.selectByCon(userParam);
return user;
}

mapper接口:

User selectByCon(UserParam userParam);

mapper.xml文件:
使用$的sql:

<select id="selectByCon" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from user2
where 1=1
<if test="username != null" >
and username = ${username}
</if>
<if test="password != null" >
and password = ${password}
</if>
</select>

数据库用户表user2数据:

运行程序:
编译后的sql:

SELECT
username,
PASSWORD
FROM
user2
WHERE
1 = 1
AND username = '李雪雷3'
OR 1 = 1
AND PASSWORD = 'ab0715'

执行结果:

登录成功:

利用了sql注入漏洞骗过了口令从而登录成功。在账号正确的前提下,密码不管输入什么都能成功登录。

说明:

如果使用$写的sql,我们可以利用sql注入漏洞来进行攻击。如果进行表的删除及数据修改sql注入,而数据库没有备份数据,那将是毁灭性的。

=============================================

使用#的sql:

<select id="selectByCon" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from user2
where 1=1
<if test="username != null" >
and username = #{username}
</if>
<if test="password != null" >
and password = #{password}
</if>
</select>

运行程序:
编译后的sql:

SELECT
username,
PASSWORD
FROM
user2
WHERE
1 = 1
AND username = ?
AND PASSWORD = ?

加入参数,翻译过来就是:

SELECT
username,
PASSWORD
FROM
user2
WHERE
1 = 1
AND username = "'李雷雷3' or 1=1"
AND PASSWORD = "'ab0715'"

执行结果:

说明:

使用#的sql进行了预编译,用?接受参数。如果是字符串的参数,则使用" "双引号括起来,有效防止了sql注入。

=========================================

补充:

预编译的好处:

在执行SQL命令时,有二种选择:可以使用PreparedStatement对象,也可以使用Statement对象。

而熟悉JDBC编程的大侠们都会选择使用PreparedStatement对象,主要因为使用预编译对象PreparedStatement时,有以下几个优点:

1、效率高

PreparedStatement可以尽可能的提高访问数据库的性能,我们都知道数据库在处理SQL语句时都有一个预编译的过程,而预编译对象就是把一些格式固定的SQL编译后,存放在内存池中即数据库缓冲池,当我们再次执行相同的SQL语句时就不需要预编译的过程了,只需DBMS运行SQL语句。所以当你需要执行Statement对象多次的时候,PreparedStatement对象将会大大降低运行时间,特别是的大型的数据库中,它可以有效的也加快了访问数据库的速度。

2、大大提高代码的可读性和可维护性

例如我们在向数据库插入数据:

一种是使用Statement对象

java.sql.Statement   stmt=conn.createStatement();

stmt.executeUpdate("insert into student (name,id,number,count) values ('"+var1+"','"+var2+"',"+var3+",'"+var4+"')");   另一种是使用PreparedStatement对象

String  sql ="insert into student values(null,?,?,?)";

java.sql.PreparedStatement pstmt=conn.preparedStatement(sql);

pstmt.setString(1,var1); pstmt.setString(2,var2); pstmt.setString(3,var3); pstmt.setString(4,var4); pstmt.executeUpdate();

使用占位符?代替

将参数与SQL语句分离出来,这样就可以方便对程序的更改和延续,同样,也可以减少不必要的错误。

3、开源防止SQL注入(最主要的)

什么时候使用预编译语句?

一般是在需要反复使用一个SQL语句时才使用预编译语句,预编译语句常常放在一个fo r或者while循环里面使用,通过反复设置参数从而多次使用该SQL语句。为了防止SQL注入漏洞,在某些数据操作中也使用预编译语句。

mybatis的sql中使用$会出现sql注入示例的更多相关文章

  1. pl/sql 中F8执行单行sql

    pl/sql中设置: tools->preferences->sql window->AutoSelect statement

  2. mybatis @Select注解中如何拼写动态sql

    @Mapper public interface DemandCommentMapper extends BaseMapper<DemandComment>{ @Select(" ...

  3. Oracle PL/SQL中的循环处理(sql for循环)

    今天来说下Oracle中的循环迭代处理,因为从自己的博客统计中看到,不少网友都搜索了关键字"SQL FOR循环",所以打算在这里说下个人的理解. PL/SQL也和我们常用的编程语言 ...

  4. MySQL开发篇(5)索引、视图、触发器、SQL中的安全问题、SQL Mode、

    一.索引 所有MySQL列类型都可以被索引,对相关列使用索引是提高SELECT操作性能的最佳途径.每种存储引擎(MyISAM.InnoDB.BDB.MEMORY等)对每个表至少支持16个索引,总索引长 ...

  5. (转)SQL中的ISNULL函数介绍

    SQL中有多种多样的函数,下面将为您介绍SQL中的ISNULL函数,包括其语法.注释.返回类型等,供您参考,希望对您学习SQL能够有所帮助. ISNULL 使用指定的替换值替换 NULL. 语法ISN ...

  6. sql中#与$取值

    在mapper.xml中#与$都是用来取值的 <update id="addUrl"> update user_power set url = #{newurl} wh ...

  7. 15 SQL中的安全问题

    SQL中的安全问题     1.SQL注入         demo1:             SELECT * FROM user WHERE username = ? AND password ...

  8. SQL SERVER调优常用方法 sql优化

    说起SQL SERVER的调优,我想大伙也很想知道这方面的知识.本人也正在探索的路上,大家有什么好的意见,欢迎一起探讨.研究.博取众人之长,才能扬长避短.本文中的内容主要是摘自<程序员的SQL金 ...

  9. mybatis动态SQL中的sql片段

    在mybatis中通过使用SQL片段可以提高代码的重用性,如下情景: 1.创建动态SQL <sql id="sql_count">select count(*)< ...

随机推荐

  1. Python笔记(八)

    #-*-coding:utf-8-*- # Python内置函数 print abs(-45) # 绝对值函数 print divmod(7,2) # 返回一个包含商和余数的元组 # input(&q ...

  2. .NET中的异步操作及线程同步

    执行异步操作 CLR使用了WIN的线程处理能力,但保留了与其分离的权利.某些时候CLR的线程与Win的线程不是完全的匹配. 线程的系统开销较大,应限制其数量. 创建:分配并初始化一线程内核对象,保留1 ...

  3. intell-

    intellect: n.[U, C] the ability to think in a logical way and understand things, especially at an ad ...

  4. iOS原生数据存储策略

    一 @interface NSCache : NSObject Description A mutable collection you use to temporarily store transi ...

  5. 【AnjularJS系列5 】— scopes、module、controller

    第五篇, scopes.module.controller 这一篇,感觉,在前面几篇就使用过的属性,但,总觉得没有理解透彻,有待完善!~ 1.scopes A.定义:$scope是一个把view(一个 ...

  6. Unity 动画资源与模型资源的区别

    动画资源: 模型资源: 对比: 模型文件多出来了 Materials + 贴图 + mesh文件,少了avatar文件 PS:动画资源,是指动画片段,即animation chip,它一般包含在模型资 ...

  7. 3DSMAX制作逼真的欧式沙发建模教程

    这篇教程是朋友们介绍利用3DSMAX制作逼真的欧式沙发建模,教程制作出来的效果真心很不错,通过这篇教程,大家可以学习沙发建模的制作方法和思路,推荐过来,一起来学习吧! 3DSMAX软件下载:http: ...

  8. Git的选项参数

    git的选项参数 MisSa@DESKTOP-PIQ06QO MINGW64 ~ $ git usage: git [--version] [--help] [-C <path>] [-c ...

  9. Spark 代码走读之 Cache

    Spark是基于内存的计算模型,但是当compute chain非常长或者某个计算代价非常大时,能将某些计算的结果进行缓存就显得很方便了.Spark提供了两种缓存的方法 Cache 和 checkPo ...

  10. WePy--记录使用过程中的一些坑

    讲真, 官方文档还是要好好看, 都是细节啊... 1- 使用wepy框架中封装好的小程序api  <wepy 对小程序的API进行Promise处理>   ①: 首先需要声明 开启使用we ...