MyBatis 排序防止sql注入
MyBatis的排序
引言
最近在專案開發中遇到一個問題,專案中使用的的MyBatis的排序功能被安全部門掃描出了SQL注入安全隱患,檢視安全報告說是有一個介面中存在SQL注入的安全漏洞,檢查後發現是因為該介面中的排序功能使用了的MyBatis中的$ {}。
#{}與$ {}的區別
預設情況下,使用#{}格式的語法會導致MyBatis的建立的PreparedStatement引數並安全地設定引數(就像使用?一樣)。這樣做更安全,更迅速,通常也是首選做法,不過有時你就是想直接在SQL語句中插入一個不轉義的字串。比如,像ORDER BY,你可以這樣來使用:ORDER BY $ {COLUMNNAME}。這裡的MyBatis不會修改或者轉義字串。
以上是官網中的說明,官網給出的解決方案是不允許使用者輸入這些欄位或者執行轉義並檢驗。顯然不允許使用者輸入這些欄位是不現實的,那麼唯一的途徑就是執行轉義並檢驗了。
解決方案
1#{}能處理嗎?
一開始想著既然#{}可以防止SQL注入,也可以設定引數,那麼就試試。先看看SQL客戶端的執行情況
測試表中只有四行記錄,預設順序如上圖,使用排序語句select * from tb_oder order by age;查詢結果如下
sql預設的排序是asc,也就是升序。那麼我修改sql語句為select * from tb_oder order by'agers';執行如何?
排序失效。我再次修改sql為select * from tb_oder order by`age`;執行結果為
排序成功,就是說這個引號是可以使用的然後我加上降序標識查詢,結果如下:
查詢成功
現在看看的MyBatis的#{}的實現:
結果並未排序,原因就是上面的第三種情況。
2.解決方案
專案中已經有多處mapperXML檔案中使用了$ {},需要寫一個通用的方式完成排序,且支援多欄位不同順序的排序。這時的MyBatis的外掛功能就用上了。請檢視之前的部落格HTTPS://blog.csdn.net/tony_java_2017/article/details/80804409
3.pageHelper排序實現
引用座標:
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.0</version>
</dependency>
在你要排序的select mapper語句前呼叫形如PageHelper.orderBy(“age desc,name”)即可;
原始碼如下