1.mybatis语句

SELECT * FROM console_operator    WHERE login_name=#{loginName} AND login_pwd=#{loginPwd}

2.日志打印信息
正确情况:username:admin, password:admin

2014-07-30 10:39:10,646 DEBUG [http-bio-8080-exec-9] com.autoyolConsole.mapper.OperatorMapper.login.BaseJdbcLogger#debug [BaseJdbcLogger.java:139] ==>  Preparing: SELECT * FROM console_operator WHERE login_name=? AND login_pwd=?
2014-07-30 10:39:10,646 DEBUG [http-bio-8080-exec-9] com.autoyolConsole.mapper.OperatorMapper.login.BaseJdbcLogger#debug [BaseJdbcLogger.java:139] ==> Parameters: admin(String), admin(String)
2014-07-30 10:39:10,661 DEBUG [http-bio-8080-exec-9] org.logicalcobwebs.proxool.null.AbstractProxyStatement#trace [AbstractProxyStatement.java:185] SELECT * FROM console_operator WHERE login_name='admin' AND login_pwd='admin'; (15 milliseconds)
2014-07-30 10:39:10,661 DEBUG [http-bio-8080-exec-9] com.autoyolConsole.mapper.OperatorMapper.login.BaseJdbcLogger#debug [BaseJdbcLogger.java:139] <== Total: 1

非法注入:admin'#

2014-07-30 10:39:10,646 DEBUG [http-bio-8080-exec-9] com.autoyolConsole.mapper.OperatorMapper.login.BaseJdbcLogger#debug [BaseJdbcLogger.java:139] ==>  Preparing: SELECT * FROM console_operator WHERE login_name=? AND login_pwd=?
2014-07-30 10:39:10,646 DEBUG [http-bio-8080-exec-9] com.autoyolConsole.mapper.OperatorMapper.login.BaseJdbcLogger#debug [BaseJdbcLogger.java:139] ==> Parameters: admin(String), admin(String)
2014-07-30 10:39:10,661 DEBUG [http-bio-8080-exec-9] org.logicalcobwebs.proxool.null.AbstractProxyStatement#trace [AbstractProxyStatement.java:185] SELECT * FROM console_operator WHERE login_name='admin'# AND login_pwd='4545'; (15 milliseconds)
2014-07-30 10:39:10,661 DEBUG [http-bio-8080-exec-9] com.autoyolConsole.mapper.OperatorMapper.login.BaseJdbcLogger#debug [BaseJdbcLogger.java:139] <== Total: 0

==>返回Total:0  注入失败~!

-----------------------------------------分割线-----------------------------------------

3.mybatis语句修改为:

SELECT * FROM console_operator    WHERE login_name=${loginName} AND login_pwd=${loginPwd}

4.日志打印信息:
非法注入情况一:'admin'#

2014-07-30 11:23:45,845 DEBUG [http-bio-8080-exec-1] com.autoyolConsole.mapper.OperatorMapper.login.BaseJdbcLogger#debug [BaseJdbcLogger.java:139] ==>  Preparing: SELECT * FROM console_operator WHERE login_name='admin'# AND login_pwd=7878
2014-07-30 11:23:45,846 DEBUG [http-bio-8080-exec-1] com.autoyolConsole.mapper.OperatorMapper.login.BaseJdbcLogger#debug [BaseJdbcLogger.java:139] ==> Parameters:
2014-07-30 11:23:45,884 DEBUG [http-bio-8080-exec-1] org.logicalcobwebs.proxool.null.AbstractProxyStatement#trace [AbstractProxyStatement.java:185] SELECT * FROM console_operator WHERE login_name='admin'# AND login_pwd=7878; (38 milliseconds)
2014-07-30 11:23:45,884 DEBUG [http-bio-8080-exec-1] com.autoyolConsole.mapper.OperatorMapper.login.BaseJdbcLogger#debug [BaseJdbcLogger.java:139] <== Total: 1

==>返回Total:1  注入成功~!

非法注入情况二:'admin' or 1=1

2014-07-30 11:26:56,943 DEBUG [http-bio-8080-exec-9] com.autoyolConsole.mapper.OperatorMapper.login.BaseJdbcLogger#debug [BaseJdbcLogger.java:139] ==>  Preparing: SELECT * FROM console_operator WHERE login_name='admin' or 1=1 AND login_pwd=7878
2014-07-30 11:26:56,944 DEBUG [http-bio-8080-exec-9] com.autoyolConsole.mapper.OperatorMapper.login.BaseJdbcLogger#debug [BaseJdbcLogger.java:139] ==> Parameters:
2014-07-30 11:26:57,002 DEBUG [http-bio-8080-exec-9] org.logicalcobwebs.proxool.null.AbstractProxyStatement#trace [AbstractProxyStatement.java:185] SELECT * FROM console_operator WHERE login_name='admin' or 1=1 AND login_pwd=7878; (58 milliseconds)
2014-07-30 11:26:57,015 DEBUG [http-bio-8080-exec-9] com.autoyolConsole.mapper.OperatorMapper.login.BaseJdbcLogger#debug [BaseJdbcLogger.java:139] <== Total: 1

==>返回Total:1  注入成功~!

综上所述:

SELECT * FROM console_operator WHERE login_name=? AND login_pwd=? 

不管输入什么参数,打印出的sql都是这样的。这是因为mybatis启用了预编译功能,在sql执行前,会先将上面的sql发送给数据库进行编译,执行时,直接使用编译好的sql,替换占位符“?”就可以了。因为sql注入只能对编译过程起作用,所以这样的方式就很好地避免了sql注入的问题。

mybatis是如何做到sql预编译的呢?其实在框架底层,是jdbc中的PreparedStatement类在起作用,PreparedStatement是我们很熟悉的Statement的子类,它的对象包含了编译好的sql语句。这种“准备好”的方式不仅能提高安全性,而且在多次执行一个sql时,能够提高效率,原因是sql已编译好,再次执行时无需再编译。

在mybatis中,”${xxx}”这样格式的参数会直接参与sql编译,从而不能避免注入攻击。但涉及到动态表名和列名时,只能使用“${xxx}”这样的参数格式,所以,这样的参数需要我们在代码中手工进行处理来防止注入。

结论:在编写mybatis的映射语句时,尽量采用“#{xxx}”这样的格式。若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止sql注入攻击。

mybatis sql注入安全的更多相关文章

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

    mybatis 学习笔记(二):mybatis SQL注入问题 SQL 注入攻击 首先了解下概念,什么叫SQL 注入: SQL注入攻击,简称SQL攻击或注入攻击,是发生于应用程序之数据库层的安全漏洞. ...

  2. mybatis sql注入

    这是${}与#{}的区别,#{}采用了预编译,在SQL执行前,会先将上面的SQL发送给数据库进行编译:执行时,直接使用编译好的SQL,替换占位符“?”就可以了.因为SQL注入只能对编译过程起作用,所以 ...

  3. Mybatis sql注入问题

    预编译方式,即PreparedStatement,可以防注入:#{id} <select id="getBlogById" resultType="Blog&quo ...

  4. mybatis中#{}与${}的差别(如何防止sql注入)

    默认情况下,使用#{}语法,MyBatis会产生PreparedStatement语句中,并且安全的设置PreparedStatement参数,这个过程中MyBatis会进行必要的安全检查和转义. # ...

  5. MyBatis怎么防止SQL注入

    SQL注入是一种代码注入技术,用于攻击数据驱动的应用,恶意的SQL语句被插入到执行的实体字段中(例如,为了转储数据库内容给攻击者).[摘自] SQL injection - Wikipedia SQL ...

  6. java持久层框架mybatis如何防止sql注入

    看到一篇很好的文章:http://www.jfox.info/ava-persistence-framework-mybatis-how-to-prevent-sql-injection sql注入大 ...

  7. MyBatis如何防止SQL注入

    转自:http://www.myexception.cn/sql/1938757.html SQL注入是一种代码注入技术,用于攻击数据驱动的应用,恶意的SQL语句被插入到执行的实体字段中(例如,为了转 ...

  8. mybatis防止sql注入

         SQL注入是一种代码注入技术,用于攻击数据驱动的应用,恶意的SQL语句被插入到执行的实体字段中(例如,为了转储数据库内容给攻击者).[摘自] SQL injection - Wikipedi ...

  9. Mybatis下的sql注入

    以前只知道mybatis框架下,order by后面接的是列名是不能用#{},这样不起效果,只能用${},这样的话就可能产生sql注入.后来发现其实还有另外两种情况也是类似的: 1.order by ...

随机推荐

  1. 大话RAC介质恢复---联机日志损坏

    对联机日志的损坏要根据日志状态进行分析,联机日志一般会有Current.Active和Inactive三种状态.Inactive状态不会造成数据丢失.而Active和Current状态的日志一般会造成 ...

  2. Python初学者笔记(4)-简单的通讯录

    要求: 编写一个简单的通讯录 1.通讯录包含至少包含姓名.电话号码.电子邮箱:2.通讯录的信息能够保存在本地磁盘:3.通讯录查找特定人员的信息:4.通讯录能够修改特定人员的信息:5.通讯录能够删除特定 ...

  3. virtualenv 安装

    virtualenv 是一个创建隔离的Python环境的工具. virtualenv要解决的根本问题是库的版本和依赖,以及权限问题.假设你有一个程序,需要LibFoo的版本1,而另一个程序需要版本2, ...

  4. Python学习教程(learning Python)--2.3.2 Python函数实参详解

    本节主要讨论函数调用时参数的实参问题. 1. 实参赋值顺序和型参定义顺序一一对应 Python在调用哪个子函数时,如果型参为多个,一般实参的排布顺序和型参顺序保持一致,即一一对应.我们以下面的代码为例 ...

  5. Linux下如何查看JDK安装路径

    1:echo $JAVA_HOME 使用$JAVA_HOME的话能定位JDK的安装路径的前提是配置了环境变量$JAVA_HOME,否则如下所示,根本定位不到JDK的安装路径 [root@localho ...

  6. 鲁棒性是 Robustness

    鲁棒性是 Robustness 的音译,是指当系统受到不正常干扰时,是否还能保证主体功能正常运作.可参考 维基百科:http://zh.wikipedia.org/zh/ 鲁棒性 _( 计算机科学 ) ...

  7. 基于xmpp openfire smack开发之Android客户端开发[3]

    在上两篇文章中,我们依次介绍openfire部署以及smack常用API的使用,这一节中我们着力介绍如何基于asmack开发一个Android的客户端,本篇的重点在实践,讲解和原理环节,大家可以参考前 ...

  8. 21.altera fpga 芯片中 pin 和 pad 区别

    在chip planner 中 ,看管脚时,会看到 pin 和pad 同时出现, 如 pin120/pad174 Bank 4 那么有什么区别? PIN指芯片封装好后的管脚,即用户看到的管脚: PAD ...

  9. 双系统下利用MbrFix.exe卸载LINUX系统

    前言:  不少同学笔记本都装的有双系统,一般都是LIUNX和WINDOWS的两个系统(由于以前对电脑各种无知)装了双系统,再次,小编就不在阐述双系统地各种不便,再次就强调一下,假若要卸载LINUX的话 ...

  10. self.a 和 _a 的区别

    在OC中我们可以通过指令@property定义属性. OC对属性封装了许多方法,同时也会自动实现一些方法,相比实例变量,感觉更加面向对象些. 一般定义属性的方法如下,在Class Test中定义属性i ...