關(guān)于mybatis使用${}時(shí)sql注入的問(wèn)題
mybatis使用${}時(shí)sql注入的問(wèn)題
最近在上線項(xiàng)目的時(shí)候,代碼審查沒有通過(guò),提示有sql注入的風(fēng)險(xiǎn)。
ORDER BY ${orderBy}
很簡(jiǎn)單的一個(gè)排序字段,但是因?yàn)槭褂?${} 占位符的原因,有sql注入的風(fēng)險(xiǎn),相信大家平時(shí)也經(jīng)常會(huì)使用這個(gè)占位符,不知道有沒有考慮sql注入的問(wèn)題,下面簡(jiǎn)單介紹下 #{} 和 ${} 的區(qū)別以及為什么使用 ${} 會(huì)有sql注入的問(wèn)題。
區(qū)別
- #{}是一個(gè)參數(shù)占位符,對(duì)于String類型會(huì)自動(dòng)加上"",其他類型不加。由于Mybatis采用預(yù)編譯,其后的參數(shù)不會(huì)再進(jìn)行SQL編譯,所以一定程度上防止SQL注入。
- ${}是一個(gè)簡(jiǎn)單的String替換,字符串是什么,解析就是什么。
- 類如order by。假如前端傳的參數(shù)是id(假設(shè)id是String類型),對(duì)于order by #{id},對(duì)應(yīng)的sql語(yǔ)句就是 order by “id”;對(duì)于order by ${id},對(duì)應(yīng)的sql語(yǔ)句則是order by id。這種情況,當(dāng)用戶傳參為id && 1=1 的時(shí)候,就會(huì)產(chǎn)生難以預(yù)計(jì)的后果。
解決方法
- 在原實(shí)體類里加入一個(gè)map
public Map<String,String> indexMap=new HashMap<String,String>(){
{
put("spaceId","space_id"); // key為前端傳的值,value為數(shù)據(jù)庫(kù)對(duì)應(yīng)的列值
put("optTime","opt_time");
}
};
- 當(dāng)傳參時(shí),判斷參數(shù)是否在map的key中,如果存在的話,就把對(duì)應(yīng)的value作為排序的依賴條件。
if(paramOptLog.getOrderBy()!=null &&Strings.isNullOrEmpty(paramOptLog.getOrderBy())){
OptLog optLog=new OptLog();
paramOptLog.setOrderBy(optLog.indexMap.getOrDefault(paramOptLog.getOrderBy(), "id"));
}
List<OptLog> list = optLogMapper.query4Page(paramOptLog);
}
- 總結(jié)就是通過(guò)映射,由程序員來(lái)決定 ${} 傳的參數(shù),即將動(dòng)態(tài)sql轉(zhuǎn)成靜態(tài)sql的方式可以解決這個(gè)問(wèn)題,這樣在實(shí)際調(diào)用的時(shí)候就不會(huì)有sql注入的風(fēng)險(xiǎn)了。
mybatis sql注入問(wèn)題之$與#
在mybatis中使用$符號(hào)
不會(huì)進(jìn)行預(yù)編譯,會(huì)被sql注入

注入方式如下:

密碼隨便輸一個(gè)就可以通過(guò)驗(yàn)證,只要用戶名正確即可。
這樣輸入后查詢語(yǔ)句在數(shù)據(jù)庫(kù)中如下:
select id,username,password from userLogin where username='admin' OR 1=1 and password='23'
sql解釋:AND優(yōu)先級(jí)高于OR 首先判斷后面1=1 and password='23'為false,然后判斷前面username='admin'為true中間
連接為OR即最后為true OR false 最后還是為true,就直接通過(guò)驗(yàn)證,能夠正常登陸admin用戶。
在mybatis中使用#符號(hào)
這樣會(huì)進(jìn)行預(yù)編譯,能夠防止sql注入。sql注入只有在編譯時(shí)才有效,而預(yù)編譯的時(shí)候是用個(gè)?代替參數(shù),真正執(zhí)行時(shí)才把參數(shù)替換?。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring根據(jù)XML配置文件 p名稱空間注入屬性的實(shí)例
下面小編就為大家分享一篇Spring根據(jù)XML配置文件 p名稱空間注入屬性的實(shí)例,具有很好的參考價(jià)值。希望對(duì)大家有所幫助2017-11-11
IntelliJ IDEA 構(gòu)建maven多模塊工程項(xiàng)目(詳細(xì)多圖)
這篇文章主要介紹了IntelliJ IDEA 構(gòu)建maven多模塊工程項(xiàng)目(詳細(xì)多圖),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
SpringBoot中請(qǐng)求參數(shù)綁定及使用詳解
這篇文章主要介紹了SpringBoot中請(qǐng)求參數(shù)綁定及使用詳解,在Web應(yīng)用程序中,請(qǐng)求參數(shù)綁定是非常重要的操作,Spring?Boot框架使得請(qǐng)求參數(shù)綁定變得非常簡(jiǎn)單,通過(guò)使用注解和預(yù)定義的類可以輕松地實(shí)現(xiàn)此操作,需要的朋友可以參考下2023-08-08
SpringBoot中@ComponentScan的使用詳解
這篇文章主要介紹了SpringBoot中@ComponentScan的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
JavaWeb實(shí)現(xiàn)Session跨頁(yè)面?zhèn)鬟f數(shù)據(jù)
本文主要介紹了 JavaWeb實(shí)現(xiàn)Session跨頁(yè)面?zhèn)鬟f數(shù)據(jù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
java枚舉enum,根據(jù)value值獲取key鍵的操作
這篇文章主要介紹了java枚舉enum,根據(jù)value值獲取key鍵的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02
SpringBoot開發(fā)詳解之Controller接收參數(shù)及參數(shù)校驗(yàn)
數(shù)據(jù)校驗(yàn)是為了使系統(tǒng)更完整,數(shù)據(jù)更精確,同時(shí)也有利于維護(hù)數(shù)據(jù)的安全性,下面這篇文章主要給大家介紹了關(guān)于SpringBoot開發(fā)詳解之Controller接收參數(shù)及參數(shù)校驗(yàn)的相關(guān)資料,需要的朋友可以參考下2022-03-03

