您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“Mybatis對SQL注入的方法是什么”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
sql注入見名思意,是指一些非法用戶通過將一些特殊字符或者sql語句插入到要提交的表單之中,從而讓服務(wù)器在不知情的情況下執(zhí)行惡意的sql命令,從而引發(fā)一系列的安全隱患。
講的通俗一點(diǎn)就是說,用戶利用sql語法將一些sql語句加在某些字段后面,提交表單的時(shí)候,服務(wù)器執(zhí)行sql命令并未達(dá)到想要的結(jié)果反而引發(fā)異常和數(shù)據(jù)泄露。
這就是典型的系統(tǒng)漏洞,因此sql注入對系統(tǒng)的危害是非常大的,做好防止sql注入也是系統(tǒng)必須完善的。
我寫了個(gè)簡單的登錄程序,框架是Spring+SpringMVC+Mybatis。表結(jié)構(gòu)如下:
可以看到當(dāng)我輸入一個(gè)特殊符號,而后臺未經(jīng)過過濾的時(shí)候,便會拋出sql異常:
并且如果沒有進(jìn)行全局異常處理,用戶便可以通過瀏覽器的開發(fā)者模式中獲取到數(shù)據(jù)庫和查詢語句的相關(guān)信息。
而這個(gè)對系統(tǒng)來說是很危險(xiǎn)的漏洞。
當(dāng)輸入正確的賬號密碼的時(shí)候,可以看到執(zhí)行時(shí)成功的。
但是如果加上這么一句sql語句在表單,我們可以看到結(jié)果依然可以執(zhí)行成功
非法用戶可以通過這個(gè)來測試數(shù)據(jù)庫的表名字、該表的其他字段名、數(shù)據(jù)的量級等等。
舉個(gè)例子:嘗試獲取到該表的其他字段名
只需要將剛才的表單中的“1=1”替換成測試sql語句即可,如果執(zhí)行成功則代表該表中有這個(gè)字段存在。
看一下最后執(zhí)行的sql語句:
就一目了然了。這通用是因?yàn)樽⑷胍鸬摹?/p>
類似的還有:'or''=' 不僅能執(zhí)行成功,同時(shí)還有查詢多全部的數(shù)據(jù)。
以上的三點(diǎn)主要是因?yàn)樵趍ybatis中使用了${}, sql語句沒有執(zhí)行預(yù)編譯,無法防止sql注入。
mybatis框架本身就有防止sql注入的特性,這就要求我們必須在寫sql語句時(shí)候遵循框架的書寫規(guī)范。
因?yàn)?{}是拼接sql字符實(shí)現(xiàn)沒有預(yù)編譯的查詢,因?yàn)槭菬o法防御sql注入,而#{}則需要進(jìn)行預(yù)編譯,可以很大程度上防止sql注入。
在一些#{}使用時(shí)候會報(bào)錯(cuò)的地方,如like 查詢、in 查詢、order by排序等,
a) like:
select * from Users where username like '%${username}%'
替換成:
select * from Users where username like concat('%', #{username}, '%')
b) in
select * from Users where id in (${id})
替換成mybatis框架自帶的foreach循環(huán):
c) order by
不要直接使用:拼接排序
如:
select *from Users order by ${id}
而是在java層面做映射,然后用<if>來做判斷
其他的類似的情況請按照相同的處理方式進(jìn)行處理即可。
SqlServer本身的防sql注入機(jī)制,利用存儲過程可以避免sql注入。應(yīng)該禁止用戶輸入一些關(guān)鍵的特殊符號,如分號、分隔符、單引號等,同時(shí)對于一些關(guān)鍵位置進(jìn)行sql關(guān)鍵字的屏蔽,如or、and等。必須對用戶輸入的內(nèi)容的類型、長度、格式、范圍進(jìn)行校驗(yàn)。
普通用戶的權(quán)限和管理員的權(quán)限之間,必須嚴(yán)格區(qū)分開來,對管理員實(shí)現(xiàn)安全級別更高的驗(yàn)證,從而防止人為獲取到更高權(quán)限時(shí)候的sql注入攻擊。
在后端代碼和數(shù)據(jù)庫中都開啟對sql注入的驗(yàn)證,同時(shí)用專業(yè)的注入工具查找本系統(tǒng)的漏洞進(jìn)行修復(fù),也可以進(jìn)行賬號誘騙,將一些如“admin”之類的容易受到攻擊的用戶設(shè)置上千位的密碼,讓攻擊者的軟件因?yàn)榻馕隽看蠖?fù)載過大,從而耗盡資源而宕機(jī)。
現(xiàn)在有一張名為student的表,表結(jié)構(gòu)如下:
其中id為自增主鍵,余下字段分別為英語成績、數(shù)學(xué)成績、美術(shù)成績、學(xué)生的學(xué)號、學(xué)生的姓名、學(xué)生的電話。
目前表里面有6條數(shù)據(jù):
使用mybatis框架實(shí)現(xiàn)根據(jù)美術(shù)成績查找相應(yīng)的記錄,在mapper.xml文件里,代碼大概會這么寫:
<!--通過美術(shù)成績作為篩選條件查詢--> <select id="queryByArtGrade" resultMap="StudentMap"> select id, english_grade, math_grade, art_grade, number, name, telephone from student <where> <if test="artGrade != null"> and art_grade = #{artGrade} </if> </where> </select>
當(dāng)然也可以這么寫:
<!--通過美術(shù)成績作為篩選條件查詢--> <select id="queryByArtGrade" resultMap="StudentMap"> select id, english_grade, math_grade, art_grade, number, name, telephone from student <where> <if test="artGrade != null"> and art_grade = ${artGrade} </if> </where> </select>
這兩種寫法的區(qū)別在于對傳入?yún)?shù)的接收方式不同,前者是#{property},后者是${property}。
想查詢美術(shù)成績?yōu)?0的記錄,使用postman進(jìn)行請求,傳入?yún)?shù)json為:
{
"artGrade":"70"
}
測試結(jié)果兩者均為:
看起來好像是一樣的結(jié)果,兩種寫法都正確。
但是我把參數(shù)改成下面的這個(gè)樣子:
{
"artGrade":"'70' and id='4'"
}
結(jié)果就完全不同啦!
使用#{property}返回的結(jié)果為空:
通過日志,發(fā)現(xiàn)實(shí)際執(zhí)行的SQL為:
select id, english_grade, math_grade, art_grade, number, name, telephone from classroom.student WHERE art_grade = "'70' and id='4'"
使用${property}返回的結(jié)果為一條:
通過日志,發(fā)現(xiàn)實(shí)際執(zhí)行的SQL為:
select id, english_grade, math_grade, art_grade, number, name, telephone from classroom.student WHERE art_grade = '70' and id='4'
“Mybatis對SQL注入的方法是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。