如何防止sql注入

edagarli發表於2014-03-16

加強對使用者輸入的驗證。
  總體來說,防治SQL隱碼攻擊式攻擊可以採用兩種方法,一是加強對使用者輸入內容的檢查與驗證;二是強迫使用引數化語句來傳遞使用者輸入的內容。在SQLServer資料庫中,有比較多的使用者輸入內容驗證工具,可以幫助管理員來對付SQL隱碼攻擊式攻擊。測試字串變數的內容,只接受所需的值。拒絕包含二進位制資料、轉義序列和註釋字元的輸入內容。這有助於防止指令碼注入,防止某些緩衝區溢位攻擊。測試使用者輸入內容的大小和資料型別,強制執行適當的限制與轉換。這即有助於防止有意造成的緩衝區溢位,對於防治注入式攻擊有比較明顯的效果。
  如可以使用儲存過程來驗證使用者的輸入。利用儲存過程可以實現對使用者輸入變數的過濾,如拒絕一些特殊的符號。如以上那個惡意程式碼中,只要儲存過程把那個分號過濾掉,那麼這個惡意程式碼也就沒有用武之地了。在執行SQL語句之前,可以通過資料庫的儲存過程,來拒絕接納一些特殊的符號。在不影響資料庫應用的前提下,應該讓資料庫拒絕包含以下字元的輸入。如分號分隔符,它是SQL隱碼攻擊式攻擊的主要幫凶。如註釋分隔符。註釋只有在資料設計的時候用的到。一般使用者的查詢語句中沒有必要註釋的內容,故可以直接把他拒絕掉,通常情況下這麼做不會發生意外損失。把以上這些特殊符號拒絕掉,那麼即使在SQL語句中嵌入了惡意程式碼,他們也將毫無作為。
  故始終通過測試型別、長度、格式和範圍來驗證使用者輸入,過濾使用者輸入的內容。這是防止SQL隱碼攻擊式攻擊的常見並且行之有效的措施。

 

普通使用者與系統管理員使用者的許可權要有嚴格的區分。
  如果一個普通使用者在使用查詢語句中嵌入另一個Drop Table語句,那麼是否允許執行呢?由於Drop語句關係到資料庫的基本物件,故要操作這個語句使用者必須有相關的許可權。在許可權設計中,對於終端使用者,即應用軟體的使用者,沒有必要給他們資料庫物件的建立、刪除等許可權。那麼即使在他們使用SQL語句中帶有嵌入式的惡意程式碼,由於其使用者許可權的限制,這些程式碼也將無法被執行。故應用程式在設計的時候,

 

 

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

 

 

多多使用SQL Server資料庫自帶的安全引數。
  為了減少注入式攻擊對於SQL Server資料庫的不良影響,在SQLServer資料庫專門設計了相對安全的SQL引數。在資料庫設計過程中,工程師要儘量採用這些引數來杜絕惡意的SQL隱碼攻擊式攻擊。
  如在SQL Server資料庫中提供了Parameters集合。這個集合提供了型別檢查和長度驗證的功能。如果管理員採用了Parameters這個集合的話,則使用者輸入的內容將被視為字元值而不是可執行程式碼。即使使用者輸入的內容中含有可執行程式碼,則資料庫也會過濾掉。因為此時資料庫只把它當作普通的字元來處理。使用Parameters集合的另外一個優點是可以強制執行型別和長度檢查,範圍以外的值將觸發異常。如果使用者輸入的值不符合指定的型別與長度約束,就會發生異常,並報告給管理員。如上面這個案例中,如果員工編號定義的資料型別為字串型,長度為10個字元。而使用者輸入的內容雖然也是字元型別的資料,但是其長度達到了20個字元。則此時就會引發異常,因為使用者輸入的內容長度超過了資料庫欄位長度的限制。

多層環境如何防治SQL隱碼攻擊式攻擊?

 

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

 

相關文章