java框架之MybatisSQL注入漏洞

嗨咯你們好...java


我是小鹿...程序員


今天呢小鹿將給你們來說解web


java框架之MybatisSQL注入漏洞數據庫


恩..前方高能...安全


請你們耐心往看完...服務器



let's go....微信


1、SQL注入漏洞基本原理架構

在常見的web漏洞中,SQL注入漏洞較爲常見,危害也較大。攻擊者一旦利用系統中存在的SQL注入漏洞來發起攻擊,在條件容許的狀況下,不只能夠獲取整站數據,還可經過進一步的滲透來獲取服務器權限,從而進入內網。app

注入攻擊的本質,是把用戶輸入的數據當作代碼執行。這裏有兩個關鍵條件,第一個是用戶可以控制輸入;第二個是本來程序要執行的代碼,拼接了用戶輸入的數據。接下來講下SQL注入漏洞的原理。框架

舉個栗子。

當用戶發送GET請求:

http://www.xxx.com/news.jsp?id=1

這是一個新聞詳情頁面,會顯示出新聞的title和content,程序內部會接收這個id參數傳遞給SQL語句,SQL以下:

SELECT title,content FROM news WHERE id = 1

這是SQL的原義,也是程序員想要獲得的結果,可是若是用戶改變了id的內容,修改爲以下:

http://www.jd.com/news.jsp?id=1 and 1=2 UNION SELECT userna-me, password FROM admin

此時內部程序執行的SQL語句爲:

SELECT title,content FROM news WHERE id = 1 and 1=2 UNION SELECT username, password FROM admin

這條SQL的原義就會被改變,致使將管理員數據表中的用戶名顯示在頁面title位置,密碼顯示在頁面content位置,攻擊成功。


2、Mybatis框架介紹
1. Mybatis框架架構

Mybatis框架架構講解(架構圖以下圖所示):

(1)加載配置:配置來源於兩個地方,一處是配置文件,一處是Java代碼的註解,將SQL的配置信息加載成爲一個個MappedStatement對象(包括了傳入參數映射配置、執行的SQL語句、結果映射配置),存儲在內存中。

(2) SQL解析:當API接口層接收到調用請求時,會接收到傳入SQL的ID和傳入對象(能夠是Map、JavaBean或者基本數據類型),Mybatis會根據SQL的ID找到對應的MappedStatement,而後根據傳入參數對象對MappedStatement進行解析,解析後能夠獲得最終要執行的SQL語句和參數。

(3)SQL執行:將最終獲得的SQL和參數拿到數據庫進行執行,獲得操做數據庫的結果。

(4)結果映射:將操做數據庫的結果按照映射的配置進行轉換,能夠轉換成HashMap、JavaBean或者基本數據類型,並將最終結果返回。

Mybatis架構圖
2. JDBC預編譯模式

Mybatis框架做爲一款半自動化的持久層框架,其SQL語句都須要咱們本身手動編寫,此時就須要按照安全編碼規範進行開發,以防止SQL注入漏洞的產生。

針對上一節中所舉的例子,應用Mybatis框架SQL語句安全寫法(即JDBC預編譯模式)能夠寫爲:

select * from news where id=#{id},這種寫法能夠很好地避免SQL注入漏洞的產生。

3. 動態拼接SQL語句

若是在開發過程當中沒有采用JDBC的預編譯模式,如咱們將上述SQL語句寫爲:select * from news where id=${id},這種寫法就產生了SQL語句的動態拼接。由於」${xxx}」這樣格式的參數會直接參與SQL語句的編譯,從而不能避免SQL注入攻擊。


3、Mybatis框架下易產生SQL注入漏洞場景分析

在基於Mybatis框架的Java白盒代碼審計工做中,一般將着手點定位在Mybatis的配置文件中。經過查看這些與數據庫交互的配置文件來肯定SQL語句中是否存在拼接狀況,進而確立跟蹤點。經過總結,Mybatis框架下易產生SQL注入漏洞的狀況主要分爲如下三種:

1. 模糊查詢like

還以第一節中提到的新聞詳情頁面爲例,按照新聞標題對新聞進行模糊查詢,若是考慮安全編碼規範問題,其對應的SQL語句以下:

Select * from news where title like ‘%#{title}%’,

但因爲這樣寫程序會報錯,研發人員將SQL查詢語句修改以下:

Select * from news where title like ‘%${title}%’,

在這種狀況下咱們發現程序再也不報錯,可是此時產生了SQL語句拼接問題,若是java代碼層面沒有對用戶輸入的內容作處理勢必會產生SQL注入漏洞。

2. in以後的參數

在對新聞進行同條件多值查詢的時候,如當用戶輸入1001,1002,1003…100N時,若是考慮安全編碼規範問題,其對應的SQL語句以下:

Select * from news where id in (#{id}),

但因爲這樣寫程序會報錯,研發人員將SQL查詢語句修改以下:

Select * from news where id in (${id}),

修改SQL語句以後,程序中止報錯,可是卻引入了SQL語句拼接的問題,若是研發人員沒有對用戶輸入的內容作過濾,勢必會產生SQL注入漏洞。

3. order by以後

當根據發佈時間、點擊量等信息對新聞進行排序的時候,若是考慮安全編碼規範問題,其對應的SQL語句以下:

Select * from news where title =‘京東’ order by #{time} asc,

但因爲發佈時間time不是用戶輸入的參數,沒法使用預編譯。研發人員將SQL查詢語句修改以下:

Select * from news where title =‘京東’ order by ${time} asc,

修改以後,程序經過預編譯,可是產生了SQL語句拼接問題,極有可能引起SQL注入漏洞。


4、Mybatis框架下SQL注入漏洞修復建議
1. 模糊查詢like SQL注入修復建議

按照新聞標題對新聞進行模糊查詢,可將SQL查詢語句設計以下:

select * from news where tile like concat(‘%’,#{title}, ‘%’),

採用預編譯機制,避免了SQL語句拼接的問題,從根源上防止了SQL注入漏洞的產生。

2.  in以後的參數SQL注入修復建議

在對新聞進行同條件多值查詢的時候,可以使用Mybatis自帶循環指令解決SQL語句動態拼接的問題:

select * from news where id in

<foreach collection="ids" item="item" open="("separator="," close=")">#{item} </foreach>

3. order by SQL注入修復建議--在Java層面作映射

預編譯機制只能處理查詢參數,其餘地方還須要研發人員根據具體狀況來解決。如前面提到的排序情景: Select * from news where title =‘京東’ order by #{time} asc,這裏time不是查詢參數,沒法使用預編譯機制,只能這樣拼接:Select * from news where title =‘京東’ order by ${time} asc 。

針對這種狀況研發人員能夠在java層面作映射來進行解決。如當存在發佈時間time和點擊量click兩種排序選擇時,咱們能夠限制用戶只能輸入1和2。當用戶輸入1時,咱們在代碼層面將其映射爲time,當用戶輸入2時,將其映射爲click。而當用戶輸入1和2以外的其餘內容時,咱們能夠將其轉換爲默認排序選擇time(或者click)。



好啦..今天就到這啦...

若是想關注更多...

Java技術資訊的話....

那麼就請...

長按下方二維碼進行關注吧....




本文分享自微信公衆號 - Java高級架構師(java968)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索