索泰gtx1070至尊plus80至尊plus灯光变成三色了

浅谈mybatis中的#和$的区别 以及防止sql注入的方法
投稿:jingxian
字体:[ ] 类型:转载 时间:
下面小编就为大家带来一篇浅谈mybatis中的#和$的区别 以及防止sql注入的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
mybatis中的#和$的区别
1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by "111", 如果传入的值是id,则解析成的sql为order by "id".
2. $将传入的数据直接显示生成在sql中。如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id,& 如果传入的值是id,则解析成的sql为order by id.
3. #方式能够很大程度防止sql注入。
4.$方式无法防止Sql注入。
5.$方式一般用于传入数据库对象,例如传入表名.
6.一般能用#的就别用$.
防止Sql注入
注意:SQL语句不要写成select * from t_stu where s_name like '%$name$%',这样极易受到注入攻击。
”${xxx}”这样格式的参数会直接参与sql编译,从而不能避免注入攻击。但涉及到动态表名和列名时,只能使用“${xxx}”这样的参数格式。
在编写mybatis的映射语句时,尽量采用“#{xxx}”这样的格式。若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止sql注入攻击。
&sql id="condition_where"&
&isNotEmpty property="companyName" prepend=" and "&
t1.company_name like #companyName#
&/isNotEmpty&
java代码和你原来的差不多,其实也没什么不好,你要觉得麻烦 把判断null和'%'封装到一个方法里就可以了
if (!StringUtil.panyName)) {
table.setCompanyName("%" + panyName + "%");
以上就是小编为大家带来的浅谈mybatis中的#和$的区别 以及防止sql注入的方法全部内容了,希望大家多多支持脚本之家~
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具mybatis做为一个轻量级ORM框架在许多项目中使用,因其简单的入门受到了广大开发者的热爱。在近期项目中再做一个相关的开发,碰到了#、$符号这样的问题,之前没怎么注意过,通过学习之后,有了点感悟,分享如下,
使用#{}意味着使用的预编译的语句,即在使用jdbc时的preparedStatement,sql语句中如果存在参数则会使用?作占位符,我们知道这种方式可以防止sql注入,并且在使用#{}时形成的sql语句,已经带有引号,例,select& * from table1 where id=#{id}& 在调用这个语句时我们可以通过后台看到打印出的sql为:select * from table1 where id='2' 加入传的值为2.也就是说在组成sql语句的时候把参数默认为字符串。
使用${}时的sql不会当做字符串处理,是什么就是什么,如上边的语句:select * from table1 where id=${id} 在调用这个语句时控制台打印的为:select * from table1 where id=2 ,假设传的参数值为2
从上边的介绍可以看出这两种方式的区别,我们最好是能用#{}则用它,因为它可以防止sql注入,且是预编译的,在需要原样输出时才使用${},如,
select * from ${tableName} order by ${id} 这里需要传入表名和按照哪个列进行排序 ,加入传入table1、id 则语句为:select * from table1 order by id
如果是使用#{} 则变成了select * from 'table1' order by 'id' 我们知道这样就不对了。
另,在使用以下的配置时,必须使用#{}
&select id="selectMessageByIdI" parameterType="int" resultType="Message"&
select * from message where id=#{id};
在parameterType是int时,sql语句中必须是#{}。
有不对之处欢迎之处!谢谢
阅读(...) 评论()sql注入大家都不陌生,是一种常见的攻击方式,攻击者在界面的表单信息或url上输入一些奇怪的sql片段,例如“or ‘1’=’1’”这样的语句,有可能入侵参数校验不足的应用。所以在我们的应用中需要做一些工作,来防备这样的攻击方式。在一些性很高的应用中,比如银行,经常使用将sql语句全部替换为过程这样的方式,来防止sql注入,这当然是一种很的方式,但我们平时中,可能不需要这种死板的方式。mybatis框架作为一款半自动化的持久层框架,其sql语句都要我们自己来手动编写,这个时候当然需要防止sql注入。其实Mybatis的sql是一个具有“输入+输出”功能,类似于函数的结构,如下:&select id="getBlogById" resultType="Blog"parameterType=”int”&
select id,title,author,content
from blog where id=#{id}
&/select&这里,parameterType标示了输入的参数类型,resultType标示了输出的参数类型。回应上文,如果我们想防止sql注入,理所当然地要在输入参数上下功夫。上面中高亮部分即输入参数在sql中拼接的部分,传入参数后,打印出执行的sql语句,会看到sql是这样的:selectid,title,author,content from blog where id = ?不管输入什么参数,打印出的sql都是这样的。这是因为mybatis启用了预功能,在sql执行前,会先将上面的sql发送给进行,执行时,直接使用编译好的sql,替换占位符“?”就可以了。因为sql注入只能对编译过程起作用,所以这样的方式就很好地避免了sql注入的问题。mybatis是如何做到sql预编译的呢?其实在框架底层,是jdbc中的PreparedStatement类在起作用,PreparedStatement是我们很熟悉的Statement的子类,它的对象包含了编译好的sql语句。这种“准备好”的方式不仅能提高,而且在多次执行一个sql时,能够提高效率,原因是sql已编译好,再次执行时无需再编译。话说回来,是否我们使用mybatis就一定可以防止sql注入呢?当然不是,请看下面的代码:&select id="orderBlog" resultType="Blog"parameterType=”map”&
select id,title,author,content
from blog order by ${orderParam}
&/select&仔细观察,内联参数的格式由“#{xxx}”变为了${xxx}。如果我们给参数“orderParam”赋值为”id”,将sql打印出来,是这样的:select id,title,author,content fromblog order by id
显然,这样是无法阻止sql注入的。在mybatis中,”${xxx}”这样格式的参数会直接参与sql编译,从而不能避免注入攻击。但涉及到表名和列名时,只能使用“${xxx}”这样的参数格式,所以,这样的参数需要我们在代码中进行处理来防止注入。
结论:在编写mybatis的映射语句时,尽量采用“#{xxx}”这样的格式。若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止sql注入攻击。博客访问: 5149640
博文数量: 543
注册时间:
高山仰止http://my.csdn.net/wzy0623王工的博客
参加炼数成金培训输入 Dataguru培训优惠码 DR50,报名立减50%固定学费。
ITPUB论坛APP
ITPUB论坛APP
APP发帖 享双倍积分
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: Java技术
上周六单位被扫描出SQL注入漏洞
经过检查,发现ibatis框架都可能出现这个问题.
如果有需求,让你实现页面grid所有字段都能排序,你会怎么做呢?
最简单的做法就是从页面把字段名,排序类型传回来,然后拼接在SQL里面.(在使用EasyUI前端框架的时候,这样做非常容易)
然后修改ibatis框架,将order by #排序字段# #排序类型#改为 order by $排序字段$ $排序类型$
实现所谓的动态查询,就像下面的链接所写的
.cn/s/blog_4dacfbb.html
实验模拟这个过程,
create table t (id int primary key ,name varchar(20),grade int);
insert into t values(1,'edmond',1);
insert into t values(2,'edmond',2);
insert into t values(3,'edmond',1);
insert into t values(4,'edmond',3);
insert into t values(5,'edmond',1);
insert into t values(6,'edmond',5);
public class Test {
&&&&private static String URL = "jdbc:mysql://127.0.0.1:3306/mvbox";
&&&&private static String USERNAME = "xx";
&&&&private static String PWD = "xx";
&&&&public static void main(String[] args) throws Exception {
&&&&&&&&//模拟从页面传输过来的参数
&&&&&&&&String name = "edmond";
&&&&&&&&String sort = "grade";
&&&&&&&&String order = "desc";
&&&&&&&&dao(name, sort, order);
&&&&private static void dao(String name, String sort, String order) throws Exception {
&&&&&&&&Class.forName("com.mysql.jdbc.Driver");
&&&&&&&&Connection con = DriverManager.getConnection(URL, USERNAME, PWD);
&&&&&&&&PreparedStatement ps = con.prepareStatement("select id,name,grade from t where name=? order by " + sort + " " + order);
&&&&&&&&ps.setString(1, name);
&&&&&&&&ResultSet rs = ps.executeQuery();
&&&&&&&&while (rs.next()) {
&&&&&&&&&&&&System.out.println(rs.getInt(1) + "\t" + rs.getString(2) + "\t" + rs.getInt(3));
&&&&&&&&con.close();
上面的代码模拟了ibatis使用$符号实现动态排序查询的场景.运行结果如下
可以看到上述代码存在注入漏洞
如果对参数order注入如下内容,即可以作为暴力攻破帐号密码的方式,又可以使用sleep挂起数据库.
String order = "desc,(select if(substring(user(),1,2)='xx',sleep(4),-1))";
攻击方式参考:
http://www.jxcm.net/shujuku/64.html
如何避免注入攻击,并且用ibatis实现动态排序查询呢?
我感觉可以使用受控注入的方式.(自己想的一个名词)
在监听器中获取数据库所有的列名称,然后使用AOP拦截DAO层的方法,
将前台传入的参数,对比监听器中获取的数据库列名称,如果没有任何匹配,则直接报错,或者给一个默认的排序
ibatis的SQL还是使用$符号的方式.
模拟代码如下
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class Test {
&&&&private static String URL = "jdbc:mysql://127.0.0.1:3306/mvbox";
&&&&private static String USERNAME = "xx";
&&&&private static String PWD = "xx";
&&&&private static List<String> fieldList = new ArrayList<String>();
&&&&private static void getAllField() throws Exception {
&&&&&&&&Class.forName("com.mysql.jdbc.Driver");
&&&&&&&&Connection con = DriverManager.getConnection(URL, USERNAME, PWD);
&&&&&&&&PreparedStatement ps = con
&&&&&&&&&&&&&&&&.prepareStatement("select column_name from information_schema.columns where table_schema not in ('information_schema','test','mysql','information_schema')");
&&&&&&&&ResultSet rs = ps.executeQuery();
&&&&&&&&while (rs.next()) {
&&&&&&&&&&&&fieldList.add(rs.getString(1));
&&&&&&&&rs.close();
&&&&&&&&ps.close();
&&&&&&&&con.close();
&&&&public static void main(String[] args) throws Exception {
&&&&&&&&// 模拟监听器启动
&&&&&&&&getAllField();
&&&&&&&&// 模拟从页面传输过来的参数
&&&&&&&&String name = "edmond";
&&&&&&&&String sort = "grade";
&&&&&&&&String order ="desc,(select if(substring(user(),1,2)='xx',sleep(4),-1))";
&&&&&&&&daoProxy(name, sort, order);
&&&&private static void daoProxy(String name, String sort, String order)
&&&&&&&&&&&&throws Exception {
&&&&&&&&if (fieldList.contains(sort)
&&&&&&&&&&&&&&&&&& (order.toLowerCase().equals("desc") || order.toLowerCase()
&&&&&&&&&&&&&&&&&&&&&&&&.equals("asc"))) {
&&&&&&&&&&&&dao(name, sort, order);
&&&&&&&&} else {
&&&&&&&&&&&&// 记录日志,进行错误处理
&&&&&&&&&&&&System.out.println("黑客,你妈妈喊你回家吃饭");
&&&&private static void dao(String name, String sort, String order)
&&&&&&&&&&&&throws Exception {
&&&&&&&&Class.forName("com.mysql.jdbc.Driver");
&&&&&&&&Connection con = DriverManager.getConnection(URL, USERNAME, PWD);
&&&&&&&&PreparedStatement ps = con
&&&&&&&&&&&&&&&&.prepareStatement("select id,name,grade from t where name=? order by "
&&&&&&&&&&&&&&&&&&&&&&&&+ sort + " " + order);
&&&&&&&&ps.setString(1, name);
&&&&&&&&ResultSet rs = ps.executeQuery();
&&&&&&&&while (rs.next()) {
&&&&&&&&&&&&System.out.println(rs.getInt(1) + "\t" + rs.getString(2) + "\t"
&&&&&&&&&&&&&&&&&&&&+ rs.getInt(3));
&&&&&&&&con.close();
可以看到,在DAO层拦截之后,在daoProxy中已经过滤了注入攻击.
这样即可以保证安全,又可以让代码优雅.
阅读(7019) | 评论(0) | 转发(0) |
相关热门文章
学习Timer类,定制自己的调度...
给主人留下些什么吧!~~
请登录后评论。}

我要回帖

更多关于 索泰gtx660 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信