數(shù)據(jù)庫預(yù)編譯為什么能防止SQL注入?
網(wǎng)友解答: 要回答這個問題,我們要知道怎么進(jìn)行的SQL注入,所謂知己知彼,方能百戰(zhàn)百勝。什么是SQL注入??所謂SQL注入,就是通過把SQL命令插入到Web表單提交或頁面請求url的查詢
要回答這個問題,我們要知道怎么進(jìn)行的SQL注入,所謂知己知彼,方能百戰(zhàn)百勝。
什么是SQL注入??
所謂SQL注入,就是通過把SQL命令插入到Web表單提交或頁面請求url的查詢字符串,最終達(dá)到欺騙服務(wù)器執(zhí)行惡意的SQL命令。具體來說,它是利用現(xiàn)有應(yīng)用程序,將(惡意)的SQL命令注入到后臺數(shù)據(jù)庫引擎執(zhí)行的能力,它可以通過在Web表單中輸入(惡意)SQL語句得到一個存在安全漏洞的網(wǎng)站上的數(shù)據(jù)庫,而不是按照設(shè)計(jì)者意圖去執(zhí)行SQL語句。
實(shí)戰(zhàn)舉例
有個登陸框如下:
可以看到除了賬號密碼之外,還有一個公司名的輸入框,根據(jù)輸入框的形式不難推出SQL的寫法如下:
SELECT * From table_name WHERE name='XX' and password='YY' and corporate='ZZ'
怎么做呢,?
因?yàn)闆]有校驗(yàn),因此,我們賬號密碼,都不填寫,直接在最后,添加 or 1=1 --
看看與上面SQL組合,成了如下:
SELECT * From table_name WHERE name='' and password='' and corporate='' or 1=1-'
從代碼可以看出,前一半單引號被閉合,后一半單引號被 “--”給注釋掉,中間多了一個永遠(yuǎn)成立的條件“1=1”,這就造成任何字符都能成功登錄的結(jié)果。
重要提醒不要以為在輸入框做個檢查就夠了,不要忘記了,我們web提交表單,是可以模擬url直接訪問過去,繞開前段檢查。因此,必須是后端,或是數(shù)據(jù)來檢查才能有效防止。
(1)檢查用戶輸入的合法性;
(2)將用戶的登錄名、密碼等數(shù)據(jù)加密保存。
(3)預(yù)處理SQL。
(4)使用存儲過程實(shí)現(xiàn)查詢,雖然不推薦,但也是一個方法。
MySQL預(yù)處理是怎么防止的呢?
其實(shí)是因?yàn)镾QL語句在程序運(yùn)行前已經(jīng)進(jìn)行了預(yù)編譯,在程序運(yùn)行時第一次操作數(shù)據(jù)庫之前,SQL語句已經(jīng)被數(shù)據(jù)庫分析,編譯和優(yōu)化,對應(yīng)的執(zhí)行計(jì)劃也會緩存下來并允許數(shù)據(jù)庫已參數(shù)化的形式進(jìn)行查詢,當(dāng)運(yùn)行時動態(tài)地把參數(shù)傳給PreprareStatement時,即使參數(shù)里有敏感字符如 or '1=1'也數(shù)據(jù)庫會作為一個參數(shù)一個字段的屬性值來處理而不會作為一個SQL指令,如此,就起到了SQL注入的作用了!
具體像這樣。例如剛剛那條SQL:
SELECT * From table_name WHERE name='' and password='' and corporate='' or 1=1-'
開啟預(yù)編譯執(zhí)行SQL的時候,則不會這么處理。會當(dāng)成一個屬性值。什么意思。隨便你怎么加,都是一個值。也就是說,如果中間有產(chǎn)生歧義的,都將被處理掉,最后執(zhí)行相當(dāng)于是這樣:
SELECT * From table_name WHERE name='' and password='' and corporate="'or 1=1--"
這個大家應(yīng)該看的懂吧,輸入的一串,都被揉在一起,作一個參數(shù),而不是SQL。
這樣就無法進(jìn)行SQL注入了。是不是很巧妙。
好了,回答完畢,你學(xué)到了嗎?
老鐵,碼字不容易哈,高抬貴手,點(diǎn)贊+關(guān)注。
網(wǎng)友解答:前幾天剛好答過,歡迎去看看:
如何從根本上防止SQL注入?https://www.wukong.com/question/6505163942816383245/
希望能對你有所幫助,謝謝。
(結(jié)束)