java框架之MybatisSQL注入漏洞

一、SQL注入漏洞基本原理

在常見的web漏洞中,SQL注入漏洞較為常見,危害也較大。攻擊者一旦利用系統(tǒng)中存在的SQL注入漏洞來發(fā)起攻擊,在條件允許的情況下,不僅可以獲取整站數(shù)據(jù),還可通過進(jìn)一步的滲透來獲取服務(wù)器權(quán)限,從而進(jìn)入內(nèi)網(wǎng)。

注入攻擊的本質(zhì),是把用戶輸入的數(shù)據(jù)當(dāng)做代碼執(zhí)行。這里有兩個(gè)關(guān)鍵條件,第一個(gè)是用戶能夠控制輸入;第二個(gè)是原本程序要執(zhí)行的代碼,拼接了用戶輸入的數(shù)據(jù)。接下來說下SQL注入漏洞的原理。

舉個(gè)栗子。

當(dāng)用戶發(fā)送GET請(qǐng)求:

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

這是一個(gè)新聞詳情頁(yè)面,會(huì)顯示出新聞的title和content,程序內(nèi)部會(huì)接收這個(gè)id參數(shù)傳遞給SQL語(yǔ)句,SQL如下:

SELECT title,content FROM news WHERE id = 1

這是SQL的原義,也是程序員想要得到的結(jié)果,但是如果用戶改變了id的內(nèi)容,修改成如下:

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

此時(shí)內(nèi)部程序執(zhí)行的SQL語(yǔ)句為:

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

這條SQL的原義就會(huì)被改變,導(dǎo)致將管理員數(shù)據(jù)表中的用戶名顯示在頁(yè)面title位置,密碼顯示在頁(yè)面content位置,攻擊成功。


二、Mybatis框架介紹

1. Mybatis框架架構(gòu)

Mybatis框架架構(gòu)講解(架構(gòu)圖如下圖所示):

(1)加載配置:配置來源于兩個(gè)地方,一處是配置文件,一處是Java代碼的注解,將SQL的配置信息加載成為一個(gè)個(gè)MappedStatement對(duì)象(包括了傳入?yún)?shù)映射配置、執(zhí)行的SQL語(yǔ)句、結(jié)果映射配置),存儲(chǔ)在內(nèi)存中。

(2)SQL解析:當(dāng)API接口層接收到調(diào)用請(qǐng)求時(shí),會(huì)接收到傳入SQL的ID和傳入對(duì)象(可以是Map、JavaBean或者基本數(shù)據(jù)類型),Mybatis會(huì)根據(jù)SQL的ID找到對(duì)應(yīng)的MappedStatement,然后根據(jù)傳入?yún)?shù)對(duì)象對(duì)MappedStatement進(jìn)行解析,解析后可以得到最終要執(zhí)行的SQL語(yǔ)句和參數(shù)。

(3)SQL執(zhí)行:將最終得到的SQL和參數(shù)拿到數(shù)據(jù)庫(kù)進(jìn)行執(zhí)行,得到操作數(shù)據(jù)庫(kù)的結(jié)果。

(4)結(jié)果映射:將操作數(shù)據(jù)庫(kù)的結(jié)果按照映射的配置進(jìn)行轉(zhuǎn)換,可以轉(zhuǎn)換成HashMap、JavaBean或者基本數(shù)據(jù)類型,并將最終結(jié)果返回。

Mybatis架構(gòu)圖

2.?JDBC預(yù)編譯模式

Mybatis框架作為一款半自動(dòng)化的持久層框架,其SQL語(yǔ)句都需要我們自己手動(dòng)編寫,此時(shí)就需要按照安全編碼規(guī)范進(jìn)行開發(fā),以防止SQL注入漏洞的產(chǎn)生。

針對(duì)上一節(jié)中所舉的例子,應(yīng)用Mybatis框架SQL語(yǔ)句安全寫法(即JDBC預(yù)編譯模式)可以寫為:

select * from news where id=#{id},這種寫法可以很好地避免SQL注入漏洞的產(chǎn)生。

3.?動(dòng)態(tài)拼接SQL語(yǔ)句

如果在開發(fā)過程中沒有采用JDBC的預(yù)編譯模式,如我們將上述SQL語(yǔ)句寫為:select * from news where id=${id},這種寫法就產(chǎn)生了SQL語(yǔ)句的動(dòng)態(tài)拼接。因?yàn)椤?{xxx}”這樣格式的參數(shù)會(huì)直接參與SQL語(yǔ)句的編譯,從而不能避免SQL注入攻擊。


三、Mybatis框架下易產(chǎn)生SQL注入漏洞場(chǎng)景分析

在基于Mybatis框架的Java白盒代碼審計(jì)工作中,通常將著手點(diǎn)定位在Mybatis的配置文件中。通過查看這些與數(shù)據(jù)庫(kù)交互的配置文件來確定SQL語(yǔ)句中是否存在拼接情況,進(jìn)而確立跟蹤點(diǎn)。通過總結(jié),Mybatis框架下易產(chǎn)生SQL注入漏洞的情況主要分為以下三種:

1. 模糊查詢like

還以第一節(jié)中提到的新聞詳情頁(yè)面為例,按照新聞標(biāo)題對(duì)新聞進(jìn)行模糊查詢,如果考慮安全編碼規(guī)范問題,其對(duì)應(yīng)的SQL語(yǔ)句如下:

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

但由于這樣寫程序會(huì)報(bào)錯(cuò),研發(fā)人員將SQL查詢語(yǔ)句修改如下:

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

在這種情況下我們發(fā)現(xiàn)程序不再報(bào)錯(cuò),但是此時(shí)產(chǎn)生了SQL語(yǔ)句拼接問題,如果java代碼層面沒有對(duì)用戶輸入的內(nèi)容做處理勢(shì)必會(huì)產(chǎn)生SQL注入漏洞。

2. in之后的參數(shù)

在對(duì)新聞進(jìn)行同條件多值查詢的時(shí)候,如當(dāng)用戶輸入1001,1002,1003…100N時(shí),如果考慮安全編碼規(guī)范問題,其對(duì)應(yīng)的SQL語(yǔ)句如下:

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

但由于這樣寫程序會(huì)報(bào)錯(cuò),研發(fā)人員將SQL查詢語(yǔ)句修改如下:

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

修改SQL語(yǔ)句之后,程序停止報(bào)錯(cuò),但是卻引入了SQL語(yǔ)句拼接的問題,如果研發(fā)人員沒有對(duì)用戶輸入的內(nèi)容做過濾,勢(shì)必會(huì)產(chǎn)生SQL注入漏洞。

3. order by之后

當(dāng)根據(jù)發(fā)布時(shí)間、點(diǎn)擊量等信息對(duì)新聞進(jìn)行排序的時(shí)候,如果考慮安全編碼規(guī)范問題,其對(duì)應(yīng)的SQL語(yǔ)句如下:

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

但由于發(fā)布時(shí)間time不是用戶輸入的參數(shù),無法使用預(yù)編譯。研發(fā)人員將SQL查詢語(yǔ)句修改如下:

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

修改之后,程序通過預(yù)編譯,但是產(chǎn)生了SQL語(yǔ)句拼接問題,極有可能引發(fā)SQL注入漏洞。


四、Mybatis框架下SQL注入漏洞修復(fù)建議

1.?模糊查詢like SQL注入修復(fù)建議

按照新聞標(biāo)題對(duì)新聞進(jìn)行模糊查詢,可將SQL查詢語(yǔ)句設(shè)計(jì)如下:

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

采用預(yù)編譯機(jī)制,避免了SQL語(yǔ)句拼接的問題,從根源上防止了SQL注入漏洞的產(chǎn)生。

2. ?in之后的參數(shù)SQL注入修復(fù)建議

在對(duì)新聞進(jìn)行同條件多值查詢的時(shí)候,可使用Mybatis自帶循環(huán)指令解決SQL語(yǔ)句動(dòng)態(tài)拼接的問題:

select * from news where id in

#{item}

3. order by SQL注入修復(fù)建議--在Java層面做映射

預(yù)編譯機(jī)制只能處理查詢參數(shù),其他地方還需要研發(fā)人員根據(jù)具體情況來解決。如前面提到的排序情景: Select * from news where title =‘京東’ order by #{time} asc,這里time不是查詢參數(shù),無法使用預(yù)編譯機(jī)制,只能這樣拼接:Select * from news where title =‘京東’ order by ${time} asc 。

針對(duì)這種情況研發(fā)人員可以在java層面做映射來進(jìn)行解決。如當(dāng)存在發(fā)布時(shí)間time和點(diǎn)擊量click兩種排序選擇時(shí),我們可以限制用戶只能輸入1和2。當(dāng)用戶輸入1時(shí),我們?cè)诖a層面將其映射為time,當(dāng)用戶輸入2時(shí),將其映射為click。而當(dāng)用戶輸入1和2之外的其他內(nèi)容時(shí),我們可以將其轉(zhuǎn)換為默認(rèn)排序選擇time(或者click)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. 簡(jiǎn)介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存儲(chǔ)過程以及高級(jí)映射的優(yōu)秀的...
    笨鳥慢飛閱讀 6,233評(píng)論 0 4
  • 姓名:于川皓 學(xué)號(hào):16140210089 轉(zhuǎn)載自:https://baike.baidu.com/item/sq...
    道無涯_cc76閱讀 2,044評(píng)論 0 2
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 34,679評(píng)論 18 399
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 4,011評(píng)論 0 11
  • 人生如戲,有天戰(zhàn)友說:“部隊(duì)怎么就不是一部電視劇呢,有我的劇終,卻少不了他們的續(xù)集!” 是??!山不轉(zhuǎn)水轉(zhuǎn),鐵打的營(yíng)...
    遠(yuǎn)方還有詩(shī)嗎閱讀 292評(píng)論 0 3

友情鏈接更多精彩內(nèi)容