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注入危險的。你說怎么防止,那我只能悲慘的告訴你,你得手動處理過濾一下輸入的內容。如判斷一下輸入的參數的長度是否正常(注入語句一般很長),更精確的過濾則可以查詢一下輸入的參數是否在預期的參數集合中。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM