MySQL處理SQL注入的另類辦法詳解。本站提示廣大學習愛好者:(MySQL處理SQL注入的另類辦法詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是MySQL處理SQL注入的另類辦法詳解正文
本文實例講述了MySQL處理SQL注入的另類辦法。分享給年夜家供年夜家參考,詳細以下:
成績解讀
我認為,這個成績每一年帶來的本錢可以高達數十億美元了。本文就來談談,假定我們有以下 SQL 模板語句:
select * from T where f1 = '{value1}' and f2 = {value2}
如今我們須要依據用戶輸出值填充該語句:
value1=hello value2=5
我們獲得了上面的 SQL 語句,我們再提交給數據庫:
select * from T where f1='hello' and f2=5
成績在於,進擊者可以結構以下的用戶輸出值:
value1=anything' or 1=1 or f1='whatever value2=5
拼接好的終究語句就釀成了:
select * from T where f1='anything' or 1=1 or f1='whatever' and f2=5
進擊者勝利地轉變了模板語句的語義。這類成績不單單產生在 SQL 上,還湧現在平日應用模板的任何說話上,好比 HTML 和 shell 劇本。
慣例處理計劃的解釋
SQL 是具有隨意率性性和分歧性的正義,token 和派生規矩組成其正義化基本。要留意的一個詞語是「隨意率性性」。與 SQL 等價的正義化數不堪數。關於這類隨意率性等價的表現,每條正當的語句都能被精確地映照到 SQL 裡的正當語句,其它說話亦然。在這類隨意率性等價表現中,假如某語句是不正當的,那末它在 SQL 裡也是不正當的。進擊者弗成能結構出可以知足任何能夠的、隨意率性與 SQL 等價的規矩。
戰略1:依據分歧的派生規矩,用另外一種語法擴大模板語句
例子1:前綴說話
SQL 應用中綴表現法注1。中綴表現法等價於 lisp 作風的前綴表現法注2。中綴與前綴:
a OP1 b OP2 c <=> (OP1 a (OP2 b c))
a、b、c 是標識符或值,OP1、OP2 是操作符或功效。
前綴表現法的示例語句:
(select * T (and (= f1 '{value1}') (= f2 {value2})))
該語句是等價的。它們在語義上屬於內涵。主動把 SQL 的中綴表現法轉換成前綴表現法或其它表現法,都不算成績了。但是,進擊者的注入在前綴語法方面就是不正當的:
(select * T (and (= f1 'anything' or 1=1 or a='whatever') (= f2 5)))
語法毛病。進擊者想要的是:
(select * T (or (= f1 'anything') (or (=1 1) (and (= a 'whatever') (= f2 5)))))
這是分歧的。進擊者的注入不克不及輸入正當的前綴說話。
例子2:歐拉表現法
另外一個替換辦法將數得著歐拉表現法了。從中綴表現法到歐拉:
a OP1 b OP2 c <=> OP1(a,OP2(b,c))
例子中的語句:
select( *,T,and(=(f1,'{value1}'),=(f2,{value2})))
而注入的語句將湧現語法毛病:
select( *,T,and(=(f1,'anything' or 1=1 or a='whatever'),=(f2,5)))
進擊者原來是想寫成:
select( *,T,or(=(f1,'anything',or(=(1,1),and(=(a,'whatever'),=(f2,5))))))
進擊者正在做毛病的工作。他的注入基本就沒有留意到所選的隨意率性標志法。
例子3:對象標志法(object notation)
還有一種替換辦法,對象標志法。早年綴表現法到對象:
a OP1 b OP2 c <=> a.OP1(b).OP2(c)
例子的代碼:
T.where(f1.=('{value1}').and(f2.=({value2})).select(*)
注入再一次折戟於語法:
T.where(f1.=('anything' or 1=1 or a='whatever').and(f2.=5)).select(*)
我不再供給准確謎底了,讀者可以當作演習,看看進擊者應當寫成甚麼模樣。
戰略2:為 SQL 選擇其它隨意率性 token
keyword 經常是一門說話裡的隨意率性 token。主要的是它們在派生規矩裡的地位、而非它們的隨意率性表現。你老是可以用其它 keyword 調換現有 keyword,而且往返轉換。舉個例子,我們可以將上面 SQL 語句中的 keyword 轉換成我們權且稱為「隨意率性的 brainfuck」:
{"select":"iph0ohKi", "*":"ieZoh4xa", "from":"aeZi5uja", "where":"OoJ4aX4n", "=":"eeQu2Zad", "(":"eiD5aera",")":"Soo2uach", "or":"Ocaig5Es"}
為了論證起見,我們將把操作數映照為 半隨意率性的構造化序列:
T <=> @phai1Oa6@T@ hello <=> @phai1Oa6@hello@
phai1Oa6 是隨意率性拔取的字符序列。關於以後情況,例子:
select * from T where f1 = '{value1}' and f2 = {value2}
釀成了:
iph0ohKi ieZoh4xa aeZi5uja @phai1Oa6@T@ OoJ4aX4n @phai1Oa6@f1@ eeQu2Zad '{value1}' @phai1Oa6@and@ @phai1Oa6@f2@ eeQu2Zad {value2}
這是正當的、隨意率性的 brainfuck 說話。經由注入以後,我們獲得了:
iph0ohKi ieZoh4xa aeZi5uja @phai1Oa6@T@ OoJ4aX4n @phai1Oa6@f1@ eeQu2Zad 'anything' or 1=1 or a='whatever' @phai1Oa6@and@ @phai1Oa6@f2@ eeQu2Zad 5
你可以看到,它包括的 token 有 'or' 和 '=',它們在隨意率性的 brainfuck 說話中是不正當的。我們的語法說,你必需如許應用:
or <=> Ocaig5Es = <=> eeQu2Zad
這些 token 也不是操作數,由於它們將只能被視作:
or <=> @phai1Oa6@or@ = <=> @phai1Oa6@=@
換句話說,注入以後的語句就變得不正當、也弗成用了。
戰略3:驗證不變量
你數數上面模板語句例子中的 token 有幾個?
[1] select [2] * [3] from [4] T [5] where [6] f1 [7] = [8] '{value1}' [9] and [10] f2 [11] = [12] {value2}
12 個。模板填充以後,總數必需依然為 12,然則我們卻看到了進擊者所激發的成果:
[1] select [2] * [3] from [4] T [5] where [6] f1 [7] = [8] 'anything' [9] or [10] 1 [11] = [12] 1 [13] or [14] a [15] = [16] 'whatever' [17] and [18] f2 [19] = [20] 5
如今有 20 個 token 。違背這類不變量,就裸露了有成績的處所。異樣實用於雷同語句的表現,除隨意率性的、brainfuck 說話。模板的填充基本弗成能招致 token 數目的變更。
現實上,你可以試著應用其它不變量,並在填充以後停止驗證。進擊者必需和它們堅持分歧。
結論
有些人倡導,法式員在填充 SQL 模板時,應當加倍當心。應對 SQL 注入成績,只是須要在編程方面多加當心。很顯著,這類方法算不上處理計劃。人們依然在校驗用戶輸出值方面湧現毛病,終究接收了帶有歹意的用戶輸出值。換句話說,單憑我們一切人更盡力地任務,是沒法基本處理這類成績的。
真實的處理計劃在於,SQL 語句自己的隨意率性性,並請求一切現存不變量都相符隨意率性的等價構造的規矩。無需法式員的干涉,就可以主動完成。
進擊者不能不相符一種未知的、隨意率性的 brainfuck 語法的規矩。想要相符一組未知的規矩,將是難以處理的成績。是以,進擊者平日沒法到手。
願望本文所述對年夜家MySQL數據庫計有所贊助。