mybatis的sql中使用$会出现sql注入示例
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注入示例的更多相关文章
- pl/sql 中F8执行单行sql
pl/sql中设置: tools->preferences->sql window->AutoSelect statement
- mybatis @Select注解中如何拼写动态sql
@Mapper public interface DemandCommentMapper extends BaseMapper<DemandComment>{ @Select(" ...
- Oracle PL/SQL中的循环处理(sql for循环)
今天来说下Oracle中的循环迭代处理,因为从自己的博客统计中看到,不少网友都搜索了关键字"SQL FOR循环",所以打算在这里说下个人的理解. PL/SQL也和我们常用的编程语言 ...
- MySQL开发篇(5)索引、视图、触发器、SQL中的安全问题、SQL Mode、
一.索引 所有MySQL列类型都可以被索引,对相关列使用索引是提高SELECT操作性能的最佳途径.每种存储引擎(MyISAM.InnoDB.BDB.MEMORY等)对每个表至少支持16个索引,总索引长 ...
- (转)SQL中的ISNULL函数介绍
SQL中有多种多样的函数,下面将为您介绍SQL中的ISNULL函数,包括其语法.注释.返回类型等,供您参考,希望对您学习SQL能够有所帮助. ISNULL 使用指定的替换值替换 NULL. 语法ISN ...
- sql中#与$取值
在mapper.xml中#与$都是用来取值的 <update id="addUrl"> update user_power set url = #{newurl} wh ...
- 15 SQL中的安全问题
SQL中的安全问题 1.SQL注入 demo1: SELECT * FROM user WHERE username = ? AND password ...
- SQL SERVER调优常用方法 sql优化
说起SQL SERVER的调优,我想大伙也很想知道这方面的知识.本人也正在探索的路上,大家有什么好的意见,欢迎一起探讨.研究.博取众人之长,才能扬长避短.本文中的内容主要是摘自<程序员的SQL金 ...
- mybatis动态SQL中的sql片段
在mybatis中通过使用SQL片段可以提高代码的重用性,如下情景: 1.创建动态SQL <sql id="sql_count">select count(*)< ...
随机推荐
- JSTL中的常用EL函数(fn:contains(str,subStr))
转自:https://blog.csdn.net/u012843873/article/details/53289238 ① fn:toLowerCase ④fn:length fn:length函数 ...
- C# Keywords - is
记录一下在日常开发过程中遇到的一些C# 基础编程的知识!希望以后能用的着.知识是在平常的开发过程中去学到的.只有用到了,你才能深入的理解它,并用好它. 本资料来源于:MSND下面是一些相关的code ...
- 比较两个时间的大小 举例:CompareDate("12:00","11:15")
//比较两个时间的大小 举例:CompareDate("12:00","11:15") function CompareDate(t1, t2) { var d ...
- 微信小程序-最新获取用户基本信息方案
如果只是单纯的展示用户信息,那么最简单的方案就是 文档中组件: <open-data type="groupName" open-gid="xxxxxx" ...
- input上传文件检测文件大小
前几天在做 input[type='file'] 上传图片时,需要检测上传文件的内存大小,写了一个小demo,在此做一总结: <!DOCTYPE html> <html lang=& ...
- [ OS ][ Linux ] [ SA ] root 帳號名稱修改
1. 背景: 由於 Linux 中預設最高權限的使用者一律為 root, 存在安全性的疑慮. 所以比較安全的作法要將 root 帳號改名為其他名稱,讓要入侵的人需要同時破解出帳號和密碼才可以進入主機, ...
- poj 2135 Farm Tour【 最小费用最大流 】
第一道费用流的题目--- 其实---还是不是很懂,只知道沿着最短路找增广路 建图 源点到1连一条容量为2(因为要来回),费用为0的边 n到汇点连一条容量为2,费用为0的边 另外的就是题目中输入的了 另 ...
- php基础-----常量const和define的区别
1.常量是一个简单的标识符,在脚本运行期间,值不可改变,默认大小写敏感. 答:使用const使得代码简单易读,const本身就是一个语言结构,而define是一个函数.另外const在编译时要比def ...
- performSelector与objc_msgSend
- perform:(SEL)aSelector { if (aSelector) return objc_msgSend(self, aSelector); else return [self er ...
- css——定位
position absolute:绝对定位 1.以页面的左上角为原点 2.不保留原来的位置 3.z-index可以调整图层顺序 如果想实现以父级元素左上角为原点.则:父级相对,子级绝对 在子级绝对的 ...