mybatis的$存在安全问题,为什么又不得不用?

1、mybatis的官网关于$和#的字符串替换符号区别描述如下:

     http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html#Parameters

上面的意思是说:假如参数columnName的值是ID,那么${columnName}会变成ID,#{columnName}会被替换成'ID',变成了字符串,注意引号。

2、对于上面的描述谈下自己的理解:

  假如你使用符号#,那么输入的参数会被看做字符串,假如你输入参数ID,最后就会变成字符串'ID';

  假如上面的的参数ID表示数据表的列名,你想根据这一列进行排序,你所期望的sql语句大概是这样:select * from tb_name order by ID,可是,你使用#符号,在xxxMapper.xml中写成下列模式:

1 <select id="queryByParams" parameterType="MyTestDO" resultMap="MyTestMap">
2         SELECT * FROM tb_name order by #{ID}
3 </select>

     最终生成的sql语句其实是这个样子:select * from tb_name order by 'ID',这样就无法实现根据列名ID进行排序的目的,因为没有列名'ID',只有列名ID,但是sql语法没有问题,可以执行。

   对于这种情况,为了防止sql注入问题,我们只能限制传入的参数内容或者形式,不能让任意的参数内容传入进来。比如下面的代码:

  

 1 String orderByType=request.getParameter(ORDER_BY_TYPE);
 2         if(StringUtils.isNotEmpty(orderByType)){
 3             if(orderByType.equals("desc")||orderByType.equals("asc")){
 4                 sqlParamFromRequest(sqlParams, ORDER_BY_TYPE);
 5             }
 6         }
 7 
 8         String orderparam=request.getParameter("orderParam");
 9         if(StringUtils.isNotEmpty(orderparam)) {
10 
11             if (orderparam.equals("normal_counting+abnormal_counting")) {
12                 sqlParams.put("orderParam", "addnew");
13 
14             } else if(orderparam.equals("normal_counting")||orderparam.equals("abnormal_counting")||orderparam.equals("emulator_counting")||orderparam.equals("app_channel")){
15 
16                 sqlParamFromRequest(sqlParams, ORDER_BY_PARME);
17             }
18         }

3、有些资料说like不能使用#符号,我实际测试,是可以用的

 对于下面需要使用拼接的情况,是可以使用#符号的,像下面写的这样:

1 <select id="queryByParams" parameterType="MyTestDO" resultMap="MyTestMap">
2     SELECT * FROM tb_shen
3     WHERE 1=1
4     <if test="name !=null">AND name LIKE CONCAT('%',#{name},'%')</if>
5 </select>

实际测试情况如下:(和上面的例子sql不符,因为这是后面修改的)


但是如果你写成下面的样子,在mybatis预处理的时候,是有问题的

  

1 <select id="queryByParams" parameterType="MyTestDO" resultMap="MyTestMap">
2         SELECT * FROM tb_shen
3         WHERE 1=1
4         <if test="name !=null">AND name LIKE CONCAT('%','#{name}','%')</if>
5 </select>

原文地址:https://www.cnblogs.com/shengulong/p/6264407.html