SQL注入與防禦技術

2021-05-25 15:35:06 字數 3714 閱讀 1874

sql注入攻擊的危害性很大。在講解其防止辦法之前,資料庫管理員有必要先了解一下其攻擊的原理。這有利於管理員採取有針對性的防治措施。

一、 sql注入攻擊的簡單示例。

statement := "select * from users where value= " + a_variable + "

上面這條語句是很普通的一條sql語句,他主要實現的功能就是讓使用者輸入乙個員工編號然後查詢處這個員工的資訊。但是若這條語句被不法攻擊者改裝過後,就可能成為破壞資料的**。如攻擊者在輸入變數的時候,輸入以下內容sa001』;drop table c_order--。那麼以上這條sql語句在執行的時候就變為了select * from users where value= 『sa001』;drop table c_order--。

這條語句是什麼意思呢?『sa001』後面的分號表示乙個查詢的結束和另一條語句的開始。c_order後面的雙連字元 指示當前行餘下的部分只是乙個注釋,應該忽略。如果修改後的**語法正確,則伺服器將執行該**。系統在處理這條語句時,將首先執行查詢語句,查到使用者編號為sa001 的使用者資訊。然後,資料將刪除表c_order(如果沒有其他主鍵等相關約束,則刪除操作就會成功)。只要注入的sql**語法正確,便無法採用程式設計方式來檢測篡改。因此,必須驗證所有使用者輸入,並仔細檢查在您所用的伺服器中執行構造 sql命令的**。

二、 sql注入攻擊原理。

可見sql注入攻擊的危害性很大。在講解其防止辦法之前,資料庫管理員有必要先了解一下其攻擊的原理。這有利於管理員採取有針對性的防治措施。

sql注入是目前比較常見的針對資料庫的一種攻擊方式。在這種攻擊方式中,攻擊者會將一些惡意**插入到字串中。然後會通過各種手段將該字串傳遞到sqlserver資料庫的例項中進行分析和執行。只要這個惡意**符合sql語句的規則,則在**編譯與執行的時候,就不會被系統所發現。

sql注入式攻擊的主要形式有兩種。一是直接將**插入到與sql命令串聯在一起並使得其以執行的使用者輸入變數。上面筆者舉的例子就是採用了這種方法。由於其直接與sql語句**,故也被稱為直接注入式攻擊法。二是一種間接的攻擊方法,它將惡意**注入要在表中儲存或者作為原書據儲存的字串。在儲存的字串中會連線到乙個動態的sql命令中,以執行一些惡意的sql**。

注入過程的工作方式是提前終止文字字串,然後追加乙個新的命令。如以直接注入式攻擊為例。就是在使用者輸入變數的時候,先用乙個分號結束當前的語句。然後再插入乙個惡意sql語句即可。由於插入的命令可能在執行前追加其他字串,因此攻擊者常常用注釋標記「—」來終止注入的字串。執行時,系統會認為此後語句位注釋,故後續的文字將被忽略,不背編譯與執行。

三、 sql注入式攻擊的防治。

既然sql注入式攻擊的危害這麼大,那麼該如何來防治呢?下面這些建議或許對資料庫管理員防治sql注入式攻擊有一定的幫助。

1、 普通使用者與系統管理員使用者的許可權要有嚴格的區分。

如果乙個普通使用者在使用查詢語句中嵌入另乙個drop table語句,那麼是否允許執行呢?由於drop語句關係到資料庫的基本物件,故要操作這個語句使用者必須有相關的許可權。在許可權設計中,對於終端使用者,即應用軟體的使用者,沒有必要給他們資料庫物件的建立、刪除等許可權。那麼即使在他們使用sql語句中帶有嵌入式的惡意**,由於其使用者許可權的限制,這些**也將無法被執行。故應用程式在設計的時候,最好把系統管理員的使用者與普通使用者區分開來。如此可以最大限度的減少注入式攻擊對資料庫帶來的危害。

2、 強迫使用引數化語句。

如果在編寫sql語句的時候,使用者輸入的變數不是直接嵌入到sql語句。而是通過引數來傳遞這個變數的話,那麼就可以有效的防治sql注入式攻擊。也就是說,使用者的輸入絕對不能夠直接被嵌入到sql語句中。與此相反,使用者的輸入的內容必須進行過濾,或者使用引數化的語句來傳遞使用者輸入的變數。引數化的語句使用引數而不是將使用者輸入變數嵌入到sql語句中。採用這種措施,可以杜絕大部分的sql注入式攻擊。不過可惜的是,現在支援引數化語句的資料庫引擎並不多。不過資料庫工程師在開發產品的時候要盡量採用引數化語句。

3、 加強對使用者輸入的驗證。

總體來說,防治sql注入式攻擊可以採用兩種方法,一是加強對使用者輸入內容的檢查與驗證;二是強迫使用引數化語句來傳遞使用者輸入的內容。在sqlserver資料庫中,有比較多的使用者輸入內容驗證工具,可以幫助管理員來對付sql注入式攻擊。測試字串變數的內容,只接受所需的值。拒絕包含二進位制資料、轉義序列和注釋字元的輸入內容。這有助於防止指令碼注入,防止某些緩衝區溢位攻擊。測試使用者輸入內容的大小和資料型別,強制執行適當的限制與轉換。這即有助於防止有意造成的緩衝區溢位,對於防治注入式攻擊有比較明顯的效果。

如可以使用儲存過程來驗證使用者的輸入。利用儲存過程可以實現對使用者輸入變數的過濾,如拒絕一些特殊的符號。如以上那個惡意**中,只要儲存過程把那個分號過濾掉,那麼這個惡意**也就沒有用武之地了。在執行sql語句之前,可以通過資料庫的儲存過程,來拒絕接納一些特殊的符號。在不影響資料庫應用的前提下,應該讓資料庫拒絕包含以下字元的輸入。如分號分隔符,它是sql注入式攻擊的主要**。如注釋分隔符。注釋只有在資料設計的時候用的到。一般使用者的查詢語句中沒有必要注釋的內容,故可以直接把他拒絕掉,通常情況下這麼做不會發生意外損失。把以上這些特殊符號拒絕掉,那麼即使在sql語句中嵌入了惡意**,他們也將毫無作為。

故始終通過測試型別、長度、格式和範圍來驗證使用者輸入,過濾使用者輸入的內容。這是防止sql注入式攻擊的常見並且行之有效的措施。

4、 多多使用sql server資料庫自帶的安全引數。

為了減少注入式攻擊對於sql server資料庫的不良影響,在sqlserver資料庫專門設計了相對安全的sql引數。在資料庫設計過程中,工程師要盡量採用這些引數來杜絕惡意的sql注入式攻擊。

如在sql server資料庫中提供了parameters集合。這個集合提供了型別檢查和長度驗證的功能。如果管理員採用了parameters這個集合的話,則使用者輸入的內容將被視為字元值而不是可執行**。即使使用者輸入的內容中含有可執行**,則資料庫也會過濾掉。因為此時資料庫只把它當作普通的字元來處理。使用parameters集合的另外乙個優點是可以強制執行型別和長度檢查,範圍以外的值將觸發異常。如果使用者輸入的值不符合指定的型別與長度約束,就會發生異常,並報告給管理員。如上面這個案例中,如果員工編號定義的資料型別為字串型,長度為10個字元。而使用者輸入的內容雖然也是字元型別的資料,但是其長度達到了20個字元。則此時就會引發異常,因為使用者輸入的內容長度超過了資料庫字段長度的限制。

5、 多層環境如何防治sql注入式攻擊?

在多層應用環境中,使用者輸入的所有資料都應該在驗證之後才能被允許進入到可信區域。未通過驗證過程的資料應被資料庫拒絕,並向上一層返回乙個錯誤資訊。實現多層驗證。對無目的的惡意使用者採取的預防措施,對堅定的攻擊者可能無效。更好的做法是在使用者介面和所有跨信任邊界的後續點上驗證輸入。如在客戶端應用程式中驗證資料可以防止簡單的指令碼注入。但是,如果下一層認為其輸入已通過驗證,則任何可以繞過客戶端的惡意使用者就可以不受限制地訪問系統。故對於多層應用環境,在防止注入式攻擊的時候,需要各層一起努力,在客戶端與資料庫端都要採用相應的措施來防治sql語句的注入式攻擊。

6、 必要的情況下使用專業的漏洞掃瞄工具來尋找可能被攻擊的點。

使用專業的漏洞掃瞄工具,可以幫助管理員來尋找可能被sql注入式攻擊的點。不過漏洞掃瞄工具只能發現攻擊點,而不能夠主動起到防禦sql注入攻擊的作用。當然這個工具也經常被攻擊者拿來使用。如攻擊者可以利用這個工具自動搜尋攻擊目標並實施攻擊。為此在必要的情況下,企業應當投資於一些專業的漏洞掃瞄工具。乙個完善的漏洞掃瞄程式不同於網路掃瞄程式,它專門查詢資料庫中的sql注入式漏洞。最新的漏洞掃瞄程式可以查詢最新發現的漏洞。所以憑藉專業的工具,可以幫助管理員發現sql注入式漏洞,並提醒管理員採取積極的措施來預防sql注入式攻擊。如果攻擊者能夠發現的sql注入式漏洞資料庫管理員都發現了並採取了積極的措施堵住漏洞,那麼攻擊者也就無從下手了。

SQL注入 SQL注入具體防禦方案

通常在開啟這兩個選項之後能防住部分sql注入漏洞被利用,因為我們之前也介紹了,在某些環境下存在繞過,在int型注入上是沒有多大作用的。通常資料汙染有兩種方式。在php5.4之前,可以利用魔術引號來解決部分sql注入的問題。而gpc在面對int型注入時,也無法進行很好的防禦。所以在通常的工作場景中,用...

sql注入繞過防禦

無waf方式已經在漏洞重溫sql注入中有描述,這裡就不多做贅述,有興趣的朋友可以去看看。內聯注釋 簡單理解 在進行演示之前,首先了解一下內聯注釋。內聯注釋通常用於繞過 安全狗,也就是俗稱的過狗。簡單來說,如果waf攔截的特徵是兩個關鍵字連線在一起,例如我們在判斷顯示位置時使用的order by,在聯...

SQL注入 如何防禦(一)

sql注入式攻擊是指利用設計上的漏洞,在目標伺服器上執行sql 命令以及進行其他方式的攻擊 string name getuserinput bookname string script select table book where book name?like?n name runsql scr...