Mybatis檢查SQL注入


Mybatis 的 Mapper.xml 語句中 parameterType 向SQL語句傳參有兩種方式:#{ } 和 ${ }。

使用#{ }是來防止SQL注入,使用${ }是用來動態拼接參數。


如何排查出

1. 檢查是否有$號

如果你使用的是ide代碼編輯器,那么可以通過全局搜索${ , 快速定位到使用${ }拼接SQL的語句,在去找到外部傳入參數的入口,閉合sql證明即可。

2. 檢查是否有order by語句

同樣的在搜索是否使用order by排序語句,如果有一步一步追蹤是否有外部參數,未過濾就直接傳遞到order by語句里面來。


為什么#{ }就安全

#{ } 就類似JDBC的預編譯,所以安全。類似如下SQL語句:(JDBC預編譯的原理,希望后面能專門去研究一下,並寫博文)

  • 使用 ${ }效果是:
select * from testtable where id="1" or true or id  # 1后面就是被攻擊者惡意構造的字符

  • 而使用#{ } 的效果是:
select * from testtable where id="1\" or true or id\""         # 1后面就是被攻擊者惡意構造的字符


什么情況下用不了#{}

答案是:在order by 排序語句的情況下不行,為什么?

先復習一下order by的用法

order by就是一個排序的工具。

# 這個1就是指第一個列索引,也可以寫id (列索引)
select * from testtable ORDER BY 1 ASC #ASC表示按升序排序,DESC表示按降序排序

# 兩個代碼是一樣的
select * from testtable ORDER BY id ASC #ASC表示按升序排序,DESC表示按降序排序


對於order by 我們是用不了#{}的,因為用了這個就會被自動轉換成字符串,自動加引號,這樣語句就不生效了。

<select id="selectStudentsByName" resultType="Student">
    select id,name,age,score from student order by #{column}
</select>

<!--編譯出來的結果如下:-->
select * from table order by 'column'

會發現加上“” 雙引號符號后,就沒法正常排序了。


如何解決:
使用${},MyBatis就不會修改或轉義改字符串。但是這樣又不安全,會導致潛在的SQL注入攻擊。所以我們需要自己去限制,不允許用戶輸入一些非法字段,通常只使用白名單方式校驗。


總結

即使是安全的sql預編譯技術,也是有適用范圍的,一些應用場景也是不適用的。當我們在做黑盒或者審計的時候,碰到了預編譯處理不了的場景,比如說排序功能的時候就得格外注意了,不然被人order by注入就悲劇了。


免責聲明!

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



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