MyBatis框架下防止SQL注入

與傳統的ORM框架不同,MyBatis使用XML描述符將對象映射到SQL語句或者存儲過程中,這種機制可以讓我們更大的靈活度通過SQL來操作數據庫對象,因此,我們必須小心這種便利下SQL注入的可能性。

安全用法

<select id="getPerson" parameterType="int" resultType="org.application.vo.Person">
SELECT * FROM PERSON WHERE ID = #{id}
</select>

這是我們推薦的一種用法,注意參數符號#{id},使用#{}語法,MyBatis會通過預編譯機制生成PreparedStatement參數,然後在安全的給參數進行賦值操作,因此就避免了SQL注入:

/* Comparable JDBC code */
String selectPerson = "SELECT * FROM PERSON WHERE ID = ?"; 
PreparedStatement ps = conn.prepareStatement(selectPerson); 
ps.setInt(1, id);

更多安全用法示例:

<insert id="insertPerson" parameterType="org.application.vo.Person">
insert into Person (id, name, email, phone)
values (#{id}, #{name}, #{email}, #{phone})
</insert>
 
<update id="updatePerson" parameterType="org.application.vo.Person">
update Person set name = #{name}, email = #{email}, phone = #{phone}
where id = #{id}
</update>
 
 
<delete id="deletePerson" parameterType="int">
delete from Person where id = #{id}
</delete>

不安全用法

<select id="getPerson" parameterType="string" resultType="org.application.vo.Person">
SELECT * FROM PERSON WHERE NAME = #{name} AND PHONE LIKE '${phone}'; 
</select>

首先,這是一種不全的用法,注意上面的參數修符號${phone} ,使用${}參數佔位修飾符,MyBatis不會對字符串做任何修改,而是直接插入到SQL語句中。這也就是說MyBatis在對參數進行替換操作時,不會對參數值進行任何修改或者轉義操作。

假設,電話號碼phone參數由用戶進行輸入,系統本身未對輸入值進行任何校驗或者轉義,那麼潛在攻擊者可能通過輸入類似:"1%' OR '1'='1"這樣的電話號碼值,那麼用戶查詢語句就會變成下面的格式:

SELECT * FROM PERSON WHERE NAME = ? and PHONE LIKE '1%' OR '1' = '1'

另外,如果電話號碼是這樣的值:A%'; DELETE FROM PERSON; --,腳本執行的結果可能就是刪除 PERSON 表中的所有記錄:

SELECT * FROM PERSON WHERE NAME = ? and PHONE LIKE 'A%'; DELETE FROM PERSON; --'

像上面這種用法,後臺直接接收用戶輸入,而不對輸入進行任何校驗都是非常危險的,這可能帶來潛在的SQL注入攻擊,因此,當我們在使用${}語法時,接受參數應不允許用戶輸入,或者允許用戶輸入,系統必須對用戶輸入進行必要的校驗和轉義。

下面是一些不安全的用法示例

<insert id="insertPerson" parameterType="org.application.vo.Person">
insert into Person (id, name, email, phone)
values (#{id}, #{name}, #{email}, ${phone})
</insert>
 
<update id="updatePerson" parameterType="org.application.vo.Person">
update Person set phone = ${phone}
where id = #{id}
</update>
 
 
<delete id="deletePerson" parameterType="int">
delete from Person where id = ${id}
</delete>

原文鏈接:
https://software-security.sans.org/developer-how-to/fix-sql-injection-in-java-mybatis

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章