• mybatis模糊查询防止SQL注入


      SQL注入,大家都不陌生,是一种常见的攻击方式。攻击者在界面的表单信息或URL上输入一些奇怪的SQL片段(例如“or ‘1’=’1’”这样的语句),有可能入侵参数检验不足的应用程序。所以,在我们的应用中需要做一些工作,来防备这样的攻击方式。在一些安全性要求很高的应用中(比如银行软件),经常使用将SQL语句全部替换为存储过程这样的方式,来防止SQL注入。这当然是一种很安全的方式,但我们平时开发中,可能不需要这种死板的方式。 

       

    1.${}模糊查询存在SQL注入的例子:(${}未编译,只是对其进行拼接,相当于Statement)

    SQL:

        <select id="getInfo2" resultType="cn.xm.exam.bean.haul.Haulinfo"
            parameterType="hashmap">
            SELECT * FROM haulinfo
            <where>
                <if test="name != null">
                    and bigname like '%${name}%'
                </if>
                <if test="status != null">
                    and bigStatus = #{status}
                </if>
            </where>
        </select>

    Java测试:

    本来是模糊查询名字,结果对描述添加了过滤。

        @Test
        public void test2() throws SQLException {
    
            Map condition = new HashMap();
            condition.put("name", "%' and bigdescription like '阳城");
            condition.put("status", "未开始");
            testMapper.getInfo2(condition);
        }

    Preparing: SELECT * FROM haulinfo WHERE bigname like '%%' and bigdescription like '阳城%' and bigStatus = ? 

    Parameters: 未开始(String)

    Total: 2

    2. bind + #{}  模糊查询 防止SQL注入 (#{}进行预编译,传递的参数不进行编译,只作为参数,相当于PreparedStatement)

    bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。比如:

    <select id="selectBlogsLike" resultType="Blog">
      <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
      SELECT * FROM BLOG
      WHERE title LIKE #{pattern}
    </select>

    例如SQL:

        <select id="getInfo" resultType="cn.xm.exam.bean.haul.Haulinfo"
            parameterType="hashmap">
            SELECT * FROM haulinfo
            <where>
                <if test="name != null">
                    <bind name="names" value="'%'+name+'%'" />
                    and bigname like #{names}
                </if>
                <if test="status != null">
                    and bigStatus = #{status}
                </if>
            </where>
        </select>

    Java测试:

        @Test
        public void test1() throws SQLException {
    
            Map condition = new HashMap();
            condition.put("name", "%' and bigdescription like '阳城");
            condition.put("status", "未开始");
            testMapper.getInfo(condition);
        }

    Preparing: SELECT * FROM haulinfo WHERE bigname like ? and bigStatus = ? 

    Parameters: %%' and bigdescription like '阳城%(String), 未开始(String)

    Total: 0

    3.另一种模糊查询方法

    select departmentid,updepartmentid,departmentname from
            department where departmentid like concat(#{departmentid},'%')
                <if test="documentName!=null &amp;&amp; documentName!=''">
                    and documentName like
                    concat(concat('%',#{documentName}),'%')
                </if>

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

    #{}:相当于JDBC中的PreparedStatement

    ${}:是输出变量的值

    简单说,#{}是经过预编译的,是安全的${}是未经过预编译的,仅仅是取变量的值,是非安全的,存在SQL注入。

      如果我们order by语句后用了${},那么不做任何处理的时候是存在SQL注入危险的。你说怎么防止,那我只能悲惨的告诉你,你得手动处理过滤一下输入的内容。如判断一下输入的参数的长度是否正常(注入语句一般很长),更精确的过滤则可以查询一下输入的参数是否在预期的参数集合中。

  • 相关阅读:
    CodeForces 706C Hard problem
    CodeForces 706A Beru-taxi
    CodeForces 706B Interesting drink
    CodeForces 706E Working routine
    CodeForces 706D Vasiliy's Multiset
    CodeForces 703B Mishka and trip
    CodeForces 703C Chris and Road
    POJ 1835 宇航员
    HDU 4907 Task schedule
    HDU 4911 Inversion
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/7818579.html
Copyright © 2020-2023  润新知