java編程——MyBatis框架中常見的SQL注入

MyBatis 是支持定製化SQL、存儲過程以及高級映射的優秀的持久層框架。由於它非常靈活,非常輕量級,受到廣大開發者的歡迎,各個大廠也用得比較多。MyBatis框架介紹相關的內容不多說,這類文章網上很多,這裡我著重介紹一下MyBatis下常見的SQL注入漏洞。

寫到一半發現有些概念要在前面說清楚一下,不然容易暈。

  • MySQL:指MySQL服務器。
  • MyBatis:指MyBatis框架。
  • JDBC:是Java用來規範數據庫連接的接口。
  • MySQL Connector/J:MySQL提供的、符合JDBC的、用來供java程序連接MySQL數據庫的jar包。俗稱:MySQL數據庫驅動。

0x01 MyBatis的SQL注入

MyBatis支持兩種參數符號,一種是#,另一種是$。

使用參數符號#的句子:

<select id="selectPerson" parameterType="int" resultType="hashmap">

SELECT * FROM PERSON WHERE ID = #{id}

select>

MyBatis會創建一個預編譯語句,生成的代碼類似於

// Similar JDBC code, NOT MyBatis…

String selectPerson = "SELECT * FROM PERSON WHERE ID=?";

PreparedStatement ps = conn.prepareStatement(selectPerson);

ps.setInt(1,id);

參數會在SQL語句中用佔位符”?”來標識,然後使用prepareStatement來預編譯這個SQL語句。

但是你以為這個SQL語句真的被MySQL數據庫預編譯了嗎?naive!其實在默認情況下,MySQL Connector/J只不過是把selectPerson做了一下轉義,前後加了雙引號,拼接到SQL語句裡面,然後再交給MySQL執行罷了

另一種使用參數符號$時,MyBatis直接用字符串拼接把參數和SQL語句拼接在一起,然後執行。眾所周知,這種情況非常危險,極容易產生SQL注入漏洞。

在使用MyBatis框架時,有以下場景極易產生SQL注入。

  1. SQL語句中的一些部分,例如order by字段、表名等,是無法使用預編譯語句的。這種場景極易產生SQL注入。推薦開發在Java層面做映射,設置一個字段/表名數組,僅允許用戶傳入索引值。這樣保證傳入的字段或者表名都在白名單裡面。
  2. like參數注入。使用如下SQL語句可防止SQL注入

like concat('%',#{title}, '%'),

3.in之後參數的SQL注入。使用如下SQL語句可防止SQL注入

id in

<foreach collection="ids" item="item" open="("separator="," close=")">

#{item}

foreach>

0x02 x-generator的SQL注入

為了提高開發效率,一些generator工具被開發出來,generator是一個從數據庫結構 自動生成實體類、Mapper接口以及對應的XML文件的工具。常見的generator有mybatis-generator,renren-generator等。

mybatis-generator是mybatis官方的一款generator。在mybatis-generator自動生成的SQL語句中,order by使用的是$,也就是簡單的字符串拼接,這種情況下極易產生SQL注入。需要開發者特別注意。

不過,mybatis-generator產生的like語句和in語句全部都是用的參數符號#,都是非常安全的實現。關注我 私信回覆【架構】或【java】獲取整個java體系的學習視頻和資料以及免費的解答還會有職業生涯規劃以及面試指導

java編程——MyBatis框架中常見的SQL注入


分享到:


相關文章: