2.SQL注入攻击
本文主要針對SQL注入的含義、以及如何進行SQL注入和如何預(yù)防SQL注入讓小伙伴有個了解。適用的人群主要是測試人員,了解如何進行SQL注入,可以幫助我們測試登錄、發(fā)布等模塊的SQL攻擊漏洞,至于如何預(yù)防SQL注入,按理說應(yīng)該是開發(fā)該了解的事情~但是作為一個棒棒的測試,搞清楚原理是不是能讓我們更加透徹地理解bug的產(chǎn)生原因呢~好啦,話不多說,進入正題~
如何理解SQL注入(攻擊)?
SQL注入是一種將SQL代碼添加到輸入?yún)?shù)中,傳遞到服務(wù)器解析并執(zhí)行的一種攻擊手法。
SQL注入攻擊是輸入?yún)?shù)未經(jīng)過濾,然后直接拼接到SQL語句當(dāng)中解析,執(zhí)行達到預(yù)想之外的一種行為,稱之為SQL注入攻擊。
?
SQL注入是怎么產(chǎn)生的?
1)WEB開發(fā)人員無法保證所有的輸入都已經(jīng)過濾
2)攻擊者利用發(fā)送給SQL服務(wù)器的輸入?yún)?shù)構(gòu)造可執(zhí)行的SQL代碼(可加入到get請求、post請求、http頭信息、cookie中)
3)數(shù)據(jù)庫未做相應(yīng)的安全配置
?
如何進行SQL注入攻擊?
以php編程語言、mysql數(shù)據(jù)庫為例,介紹一下SQL注入攻擊的構(gòu)造技巧、構(gòu)造方法
1.數(shù)字注入
在瀏覽器地址欄輸入:learn.me/sql/article.php?id=1,這是一個get型接口,發(fā)送這個請求相當(dāng)于調(diào)用一個查詢語句:
?
$sql = "SELECT * FROM article WHERE id =",$id正常情況下,應(yīng)該返回一個id=1的文章信息。那么,如果在瀏覽器地址欄輸入:learn.me/sql/article.php?id=-1 OR 1 =1,這就是一個SQL注入攻擊了,可能會返回所有文章的相關(guān)信息。為什么會這樣呢?
這是因為,id = -1永遠是false,1=1永遠是true,所有整個where語句永遠是ture,所以where條件相當(dāng)于沒有加where條件,那么查詢的結(jié)果相當(dāng)于整張表的內(nèi)容
2.字符串注入
有這樣一個用戶登錄場景:登錄界面包括用戶名和密碼輸入框,以及提交按鈕。輸入用戶名和密碼,提交。
這是一個post請求,登錄時調(diào)用接口learn.me/sql/login.html,首先連接數(shù)據(jù)庫,然后后臺對post請求參數(shù)中攜帶的用戶名、密碼進行參數(shù)校驗,即sql的查詢過程。假設(shè)正確的用戶名和密碼為user和pwd123,輸入正確的用戶名和密碼、提交,相當(dāng)于調(diào)用了以下的SQL語句:
?
SELECT * FROM user WHERE username = 'user' ADN password = 'pwd123'?
由于用戶名和密碼都是字符串,SQL注入方法即把參數(shù)攜帶的數(shù)據(jù)變成mysql中注釋的字符串。mysql中有2種注釋的方法:
1)'#':'#'后所有的字符串都會被當(dāng)成注釋來處理
用戶名輸入:user'#(單引號閉合user左邊的單引號),密碼隨意輸入,如:111,然后點擊提交按鈕。等價于SQL語句:
?
SELECT * FROM user WHERE username = 'user'#'ADN password = '111'?
'#'后面都被注釋掉了,相當(dāng)于:
?
SELECT * FROM user WHERE username = 'user'?
2)'-- ' (--后面有個空格):'-- '后面的字符串都會被當(dāng)成注釋來處理
用戶名輸入:user'-- (注意--后面有個空格,單引號閉合user左邊的單引號),密碼隨意輸入,如:111,然后點擊提交按鈕。等價于SQL語句:
?
SELECT * FROM user WHERE username = 'user'-- 'AND password = '111'SELECT * FROM user WHERE username = 'user'-- 'AND password = '1111'
?
'-- '后面都被注釋掉了,相當(dāng)于:
SELECT * FROM user WHERE username = 'user'因此,以上兩種情況可能輸入一個錯誤的密碼或者不輸入密碼就可登錄用戶名為'user'的賬號,這是十分危險的事情。
?
如何預(yù)防SQL注入?
這是開發(fā)人員應(yīng)該思考的問題,作為測試人員,了解如何預(yù)防SQL注入,可以在發(fā)現(xiàn)注入攻擊bug時,對bug產(chǎn)生原因進行定位。
1)嚴(yán)格檢查輸入變量的類型和格式
對于整數(shù)參數(shù),加判斷條件:不能為空、參數(shù)類型必須為數(shù)字
對于字符串參數(shù),可以使用正則表達式進行過濾:如:必須為[0-9a-zA-Z]范圍內(nèi)的字符串
2)過濾和轉(zhuǎn)義特殊字符
在username這個變量前進行轉(zhuǎn)義,對'、"、\等特殊字符進行轉(zhuǎn)義,如:php中的addslashes()函數(shù)對username參數(shù)進行轉(zhuǎn)義
3)利用mysql的預(yù)編譯機制
把sql語句的模板(變量采用占位符進行占位)發(fā)送給mysql服務(wù)器,mysql服務(wù)器對sql語句的模板進行編譯,編譯之后根據(jù)語句的優(yōu)化分析對相應(yīng)的索引進行優(yōu)化,在最終綁定參數(shù)時把相應(yīng)的參數(shù)傳送給mysql服務(wù)器,直接進行執(zhí)行,節(jié)省了sql查詢時間,以及mysql服務(wù)器的資源,達到一次編譯、多次執(zhí)行的目的,除此之外,還可以防止SQL注入。具體是怎樣防止SQL注入的呢?實際上當(dāng)將綁定的參數(shù)傳到mysql服務(wù)器,mysql服務(wù)器對參數(shù)進行編譯,即填充到相應(yīng)的占位符的過程中,做了轉(zhuǎn)義操作。
總結(jié)
- 上一篇: 总结:ps aux指令
- 下一篇: 数据库:索引