欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

技巧和訣竅防范SQL注入攻擊

 更新時間:2007年03月12日 00:00:00   作者:  
【原文地址】Tip/Trick: Guard Against SQL Injection Attacks 
【原文發(fā)表日期】 Saturday, September 30, 2006 9:11 AM

SQL注入攻擊是非常令人討厭的安全漏洞,是所有的web開發(fā)人員,不管是什么平臺,技術(shù),還是數(shù)據(jù)層,需要確信他們理解和防止的東西。不幸的是,開發(fā)人員往往不集中花點時間在這上面,以至他們的應(yīng)用,更糟糕的是,他們的客戶極其容易受到攻擊。

Michael Sutton 最近發(fā)表了一篇非常發(fā)人深省的帖子,講述在公共網(wǎng)上這問題是多么地普遍。他用Google的Search API建了一個C#的客戶端程序,尋找那些易受SQL 注入攻擊的網(wǎng)站。其步驟很簡單:

尋找那些帶查詢字符串的網(wǎng)站(例如,查詢那些在URL里帶有 "id=" 的URL) 
給這些確定為動態(tài)的網(wǎng)站發(fā)送一個請求,改變其中的id=語句,帶一個額外的單引號,來試圖取消其中的SQL語句(例如,如 id=6' ) 
分析返回的回復(fù),在其中查找象“SQL” 和“query”這樣的詞,這往往表示應(yīng)用返回了詳細(xì)的錯誤消息(這本身也是很糟糕的) 
檢查錯誤消息是否表示發(fā)送到SQL服務(wù)器的參數(shù)沒有被正確加碼(encoded),如果如此,那么表示可對該網(wǎng)站進(jìn)行SQL注入攻擊
對通過Google搜尋找到的1000個網(wǎng)站的隨機(jī)取樣測試,他檢測到其中的11.3%有易受SQL注入攻擊的可能。這非常,非常地可怕。這意味著黑客可以遠(yuǎn)程利用那些應(yīng)用里的數(shù)據(jù),獲取任何沒有hashed或加密的密碼或信用卡數(shù)據(jù),甚至有以管理員身份登陸進(jìn)這些應(yīng)用的可能。這不僅對開發(fā)網(wǎng)站的開發(fā)人員來說很糟糕,而且對使用網(wǎng)站的消費者或用戶來說更糟糕,因為他們給網(wǎng)站提供了數(shù)據(jù),想著網(wǎng)站是安全的呢。

那么SQL注入攻擊到底是什么玩意?

有幾種情形使得SQL注入攻擊成為可能。最常見的原因是,你動態(tài)地構(gòu)造了SQL語句,卻沒有使用正確地加了碼(encoded)的參數(shù)。譬如,考慮這個 SQL查詢的編碼,其目的是根據(jù)由查詢字符串提供的社會保險號碼(social security number)來查詢作者(Authors):


Dim SSN as String
Dim SqlQuery as String

SSN = Request.QueryString("SSN")
SqlQuery = "SELECT au_lname, au_fname FROM authors WHERE au_id = '" + SSN + "'" 

如果你有象上面這個片斷一樣的SQL編碼,那么你的整個數(shù)據(jù)庫和應(yīng)用可以遠(yuǎn)程地被黑掉。怎么會呢?在普通情形下,用戶會使用一個社會保險號碼來訪問這個網(wǎng)站,編碼是象這樣執(zhí)行的:


' URL to the page containing the above code
http://mysite.com/listauthordetails.aspx?SSN=172-32-9999

' SQL Query executed against the database 
SELECT au_lname, au_fname FROM authors WHERE au_id = '172-32-9999' 

這是開發(fā)人員預(yù)期的做法,通過社會保險號碼來查詢數(shù)據(jù)庫中作者的信息。但因為參數(shù)值沒有被正確地加碼,黑客可以很容易地修改查詢字符串的值,在要執(zhí)行的值后面嵌入附加的SQL語句 。譬如,


' URL to the page containing the above code
http://mysite.com/listauthordetails.aspx?SSN=172-32-9999 ';DROP DATABASE pubs --

' SQL Query executed against the database 
SELECT au_lname, au_fname FROM authors WHERE au_id = '';DROP DATABASE pubs -- 
注意到?jīng)]有,我可以在SSN查詢字符串值的后面添加“ ';DROP DATABASE pubs -- ”,通過 “;”字符來終止當(dāng)前的SQL語句,然后添加了我自己的惡意的SQL語句,然后把語句的其他部分用“--”字符串注釋掉。因為我們是手工在編碼里構(gòu)造SQL語句,我們最后把這個字符串傳給了數(shù)據(jù)庫,數(shù)據(jù)庫會先對authors表進(jìn)行查詢,然后把我們的pubs數(shù)據(jù)庫刪除。“砰(bang)”的一聲,數(shù)據(jù)庫就沒了!

萬一你認(rèn)為匿名黑客刪除你的數(shù)據(jù)庫的結(jié)果很壞,但不幸的是,實際上,這在SQL注入攻擊所涉及的情形中算是比較好的。一個黑客可以不單純摧毀數(shù)據(jù),而是使用上面這個編碼的弱點,執(zhí)行一個JOIN語句,來獲取你數(shù)據(jù)庫里的所有數(shù)據(jù),顯示在頁面上,允許他們獲取用戶名,密碼,信用卡號碼等等。他們也可以添加  UPDATE/INSERT 語句改變產(chǎn)品的價格,添加新的管理員賬號,真的搞砸你(screw up your life)呢。想象一下,到月底檢查庫存時,發(fā)現(xiàn)你庫房里的實際產(chǎn)品數(shù)與你的帳目系統(tǒng)(accounting system)匯報的數(shù)目有所不同。。。

那該如何保護(hù)你自己?

SQL注入攻擊是你需要擔(dān)心的事情,不管你用什么web編程技術(shù),再說所有的web框架都需要擔(dān)心這個的。你需要遵循幾條非常基本的規(guī)則:

1)  在構(gòu)造動態(tài)SQL語句時,一定要使用類安全(type-safe)的參數(shù)加碼機(jī)制。大多數(shù)的數(shù)據(jù)API,包括ADO和ADO.NET,有這樣的支持,允許你指定所提供的參數(shù)的確切類型(譬如,字符串,整數(shù),日期等),可以保證這些參數(shù)被恰當(dāng)?shù)豦scaped/encoded了,來避免黑客利用它們。一定要從始到終地使用這些特性。 

例如,在ADO.NET里對動態(tài)SQL,你可以象下面這樣重寫上述的語句,使之安全: 

Dim SSN as String = Request.QueryString("SSN")

Dim cmd As new SqlCommand("SELECT au_lname, au_fname FROM authors WHERE au_id = @au_id")
Dim param = new SqlParameter("au_id", SqlDbType.VarChar)
param.Value = SSN
cmd.Parameters.Add(param) 
這將防止有人試圖偷偷注入另外的SQL表達(dá)式(因為ADO.NET知道對au_id的字符串值進(jìn)行加碼),以及避免其他數(shù)據(jù)問題(譬如不正確地轉(zhuǎn)換數(shù)值類型等)。注意,VS 2005內(nèi)置的TableAdapter/DataSet設(shè)計器自動使用這個機(jī)制,ASP.NET 2.0數(shù)據(jù)源控件也是如此。 

一個常見的錯誤知覺(misperception)是,假如你使用了存儲過程或ORM,你就完全不受SQL注入攻擊之害了。這是不正確的,你還是需要確定在給存儲過程傳遞數(shù)據(jù)時你很謹(jǐn)慎,或在用ORM來定制一個查詢時,你的做法是安全的。 

2)  在部署你的應(yīng)用前,始終要做安全審評(security review)。建立一個正式的安全過程 (formal security process),在每次你做更新時,對所有的編碼做審評。后面一點特別重要。很多次我聽說開發(fā)隊伍在正式上線 (going live)前會做很詳細(xì)的安全審評,然后在幾周或幾個月之后他們做一些很小的更新時,他們會跳過安全審評這關(guān),推說,“就是一個小小的更新,我們以后再做編碼審評好了”。請始終堅持做安全審評。

3) 千萬別把敏感性數(shù)據(jù)在數(shù)據(jù)庫里以明文存放。我個人的意見是,密碼應(yīng)該總是在單向(one-way )hashed過后再存放,我甚至不喜歡將它們在加密后存放。在默認(rèn)設(shè)置下, ASP.NET 2.0 Membership API 自動為你這么做,還同時實現(xiàn)了安全的SALT 隨機(jī)化行為 (SALT randomization behavior)。如果你決定建立自己的成員數(shù)據(jù)庫,我建議你查看一下我們在這里發(fā)表的我們自己的 Membership provider的源碼。同時也確定對你的數(shù)據(jù)庫里的信用卡和其他的私有數(shù)據(jù)進(jìn)行了加密。這樣即使你的數(shù)據(jù)庫被人入侵 (compromised)了的話,起碼你的客戶的私有數(shù)據(jù)不會被人利用。

4) 確認(rèn)你編寫了自動化的單元測試,來特別校驗?zāi)愕臄?shù)據(jù)訪問層和應(yīng)用程序不受SQL注入攻擊。這么做是非常重要的,有助于捕捉住(catch)“就是一個小小的更新,所有不會有安全問題”的情形帶來的疏忽,來提供額外的安全層以避免偶然地引進(jìn)壞的安全缺陷到你的應(yīng)用里去。

5) 鎖定你的數(shù)據(jù)庫的安全,只給訪問數(shù)據(jù)庫的web應(yīng)用功能所需的最低的權(quán)限。如果web應(yīng)用不需要訪問某些表,那么確認(rèn)它沒有訪問這些表的權(quán)限。如果web應(yīng)用只需要只讀的權(quán)限從你的account payables表來生成報表,那么確認(rèn)你禁止它對此表的 insert/update/delete 的權(quán)限。

如何了解更多的相關(guān)知識

微軟Prescriptive Architecture Guidance (PAG)產(chǎn)品組發(fā)表了許多非常棒的安全指導(dǎo)方針方面的文檔,你應(yīng)該留出些時間來閱讀一下: 

ASP.NET 2.0 安全指定方針 
ASP.NET 2.0 安全部署清單 
ASP.NET 2.0 安全實踐概述 
Web應(yīng)用工程安全索引 
如何對托管編碼進(jìn)行安全編碼審評 
ASP.NET 2.0 安全問題列表 
ASP.NET 2.0 安全培訓(xùn)單元(Training Modules)
此外,還有這些其他的PAG How-To文章對進(jìn)一步了解如何保護(hù)你免受注入攻擊大有用處:

如何在ASP.NET里防范表單注入攻擊 
如何在ASP.NET里防范SQL注入攻擊
你還可以在我寫的這篇關(guān)于安全的博客帖子以及我的ASP.NET 技巧和訣竅頁上找到關(guān)于ASP.NET安全方面的有用的信息。

更新: Bertrand給我指出了他2年前寫的這篇關(guān)于SQL注入攻擊的非常棒的帖子,非常值得一讀。

希望本文對你有所幫助,

Scott

相關(guān)文章

最新評論