天天看點

ASP.NET網站程式防SQL注入式攻擊方法

ASP.NET網站程式防SQL注入式攻擊方法

一、什麼是SQL注入式攻擊?

所謂SQL注入式攻擊,就是攻擊者把SQL指令插入到Web表單的輸入域或頁面請求的查詢字元串,欺騙伺服器執行惡意的SQL指令。在某些表單中,使用者輸入的内容直接用來構造(或者影響)動态SQL指令,或作為存儲過程的輸入參數,這類表單特别容易受到SQL注入式攻擊。常見的SQL注入式攻擊過程類如:

⑴ 某個ASP.NET Web應用有一個登入頁面,這個登入頁面控制着使用者是否有權通路應用,它要求使用者輸入一個名稱和密碼。

⑵ 登入頁面中輸入的内容将直接用來構造動态的SQL指令,或者直接用作存儲過程的參數。下面是ASP.NET應用構造查詢的一個例子:

System.Text.StringBuilder query = new System.Text.StringBuilder( 

"SELECT * from Users WHERE login = '") 

.Append(txtLogin.Text).Append("' AND password='") 

.Append(txtPassword.Text).Append("'");

⑶ 攻擊者在使用者名字和密碼輸入框中輸入"'或'1'='1"之類的内容。

⑷ 使用者輸入的内容送出給伺服器之後,伺服器運作上面的ASP.NET代碼構造出查詢使用者的SQL指令,但由于攻擊者輸入的内容非常特殊,是以最後得到的SQL指令變成:SELECT * from Users WHERE login = '' or '1'='1' AND password = '' or '1'='1'。

⑸ 伺服器執行查詢或存儲過程,将使用者輸入的身份資訊和伺服器中儲存的身份資訊進行對比。

⑹ 由于SQL指令實際上已被注入式攻擊修改,已經不能真正驗證使用者身份,是以系統會錯誤地授權給攻擊者。

如果攻擊者知道應用會将表單中輸入的内容直接用于驗證身份的查詢,他就會嘗試輸入某些特殊的SQL字元串篡改查詢改變其原來的功能,欺騙系統授予通路權限。

系統環境不同,攻擊者可能造成的損害也不同,這主要由應用通路資料庫的安全權限決定。如果使用者的帳戶具有管理者或其他比較進階的權限,攻擊者就可能對資料庫的表執行各種他想要做的操作,包括添加、删除或更新資料,甚至可能直接删除表。

二、如何防範?

好在要防止ASP.NET應用被SQL注入式攻擊闖入并不是一件特别困難的事情,隻要在利用表單輸入的内容構造SQL指令之前,把所有輸入内容過濾一番就可以了。過濾輸入内容可以按多種方式進行。

⑴ 對于動态構造SQL查詢的場合,可以使用下面的技術:

第一:替換單引号,即把所有單獨出現的單引号改成兩個單引号,防止攻擊者修改SQL指令的含義。再來看前面的例子,“SELECT * from Users WHERE login = ''' or ''1''=''1' AND password = ''' or ''1''=''1'”顯然會得到與“SELECT * from Users WHERE login = '' or '1'='1' AND password = '' or '1'='1'”不同的結果。

第二:删除使用者輸入内容中的所有連字元,防止攻擊者構造出類如“SELECT * from Users WHERE login = 'mas' -- AND password =''”之類的查詢,因為這類查詢的後半部分已經被注釋掉,不再有效,攻擊者隻要知道一個合法的使用者登入名稱,根本不需要知道使用者的密碼就可以順利獲得通路權限。

第三:對于用來執行查詢的資料庫帳戶,限制其權限。用不同的使用者帳戶執行查詢、插入、更新、删除操作。由于隔離了不同帳戶可執行的操作,因而也就防止了原本用于執行SELECT指令的地方卻被用于執行INSERT、UPDATE或DELETE指令。

⑵ 用存儲過程來執行所有的查詢。SQL參數的傳遞方式将防止攻擊者利用單引号和連字元實施攻擊。此外,它還使得資料庫權限可以限制到隻允許特定的存儲過程執行,所有的使用者輸入必須遵從被調用的存儲過程的安全上下文,這樣就很難再發生注入式攻擊了。

⑶ 限制表單或查詢字元串輸入的長度。如果使用者的登入名字最多隻有10個字元,那麼不要認可表單中輸入的10個以上的字元,這将大大增加攻擊者在SQL指令中插入有害代碼的難度。

⑷ 檢查使用者輸入的合法性,确信輸入的内容隻包含合法的資料。資料檢查應當在用戶端和伺服器端都執行——之是以要執行伺服器端驗證,是為了彌補用戶端驗證機制脆弱的安全性。

在用戶端,攻擊者完全有可能獲得網頁的源代碼,修改驗證合法性的腳本(或者直接删除腳本),然後将非法内容通過修改後的表單送出給伺服器。是以,要保證驗證操作确實已經執行,唯一的辦法就是在伺服器端也執行驗證。你可以使用許多内建的驗證對象,例如RegularExpressionValidator,它們能夠自動生成驗證用的用戶端腳本,當然你也可以插入伺服器端的方法調用。如果找不到現成的驗證對象,你可以通過CustomValidator自己建立一個。

⑸ 将使用者登入名稱、密碼等資料加密儲存。加密使用者輸入的資料,然後再将它與資料庫中儲存的資料比較,這相當于對使用者輸入的資料進行了“消毒”處理,使用者輸入的資料不再對資料庫有任何特殊的意義,進而也就防止了攻擊者注入SQL指令。System.Web.Security.FormsAuthentication類有一個HashPasswordForStoringInConfigFile,非常适合于對輸入資料進行消毒處理。

⑹ 檢查提取資料的查詢所傳回的記錄數量。如果程式隻要求傳回一個記錄,但實際傳回的記錄卻超過一行,那就當作出錯處理。

文章轉載自網管之家:http://www.bitscn.com/network/protect/200811/154973.html

六個建議防止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注入式漏