色尼玛亚洲综合影院,亚洲3atv精品一区二区三区,麻豆freexxxx性91精品,欧美在线91

使用LINQ解除SQL注入安全問(wèn)題

在開(kāi)發(fā)人員承受越來(lái)越多的安全責(zé)任之時(shí),許多開(kāi)發(fā)人員了解到的第一個(gè)Web應(yīng)用安全漏洞,是一個(gè)被稱為“SQL注入”的極危險(xiǎn)的命令注入形式。命令注入的原始的形式本是指這樣一種漏洞:攻擊者通過(guò)提供一個(gè)正常使用者意料之外的輸入,改變你的Web應(yīng)用程序的運(yùn)行方式,從而允許攻擊者運(yùn)行服務(wù)器上的非授權(quán)的命令。無(wú)疑,SQL注入式攻擊是很常見(jiàn)的、被廣泛使用的攻擊形式。幸運(yùn)的是,一旦我們理解了這個(gè)問(wèn)題,就可以很容易地防止SQL注入式攻擊。更妙的是,現(xiàn)在微軟的數(shù)據(jù)訪問(wèn)技術(shù)向.NET開(kāi)發(fā)人員提供了徹底地清除SQL注入漏洞的機(jī)會(huì),當(dāng)然前提是能夠正確使用。這種技術(shù)稱為“語(yǔ)言級(jí)集成查詢”(Language Integrated Query (LINQ)),并隨Visual Studio "Orcas" 和 .NET Framework 3.5一起發(fā)布。本文將討論如何通過(guò)LINQ強(qiáng)化Web應(yīng)用程序的數(shù)據(jù)訪問(wèn)代碼,從而解決通過(guò)SQL注入進(jìn)行攻擊的問(wèn)題。

SQL注入是一種Web應(yīng)用程序的安全漏洞,通過(guò)它攻擊者可以將惡意數(shù)據(jù)提交給應(yīng)用程序,欺騙應(yīng)用程序在服務(wù)器上執(zhí)行惡意的SQL命令。理論上講,這種攻擊是容易預(yù)防的,不過(guò)由于其允許攻擊者直接運(yùn)行針對(duì)用戶關(guān)鍵數(shù)據(jù)的數(shù)據(jù)庫(kù)命令,從而成為一種常見(jiàn)的、危害性大的攻擊形式。在非常極端的情況下,攻擊者不但能夠自由地控制用戶的數(shù)據(jù),還可以刪除數(shù)據(jù)表和數(shù)據(jù)庫(kù),甚至控制整個(gè)數(shù)據(jù)庫(kù)服務(wù)器

如果這種攻擊容易預(yù)防,那么為什么還如此危險(xiǎn)呢?首先,由于眾所周知的經(jīng)濟(jì)上的原因,你的應(yīng)用數(shù)據(jù)庫(kù)是非常誘人的,可以引起攻擊者的極大注意。如果SQL注入漏洞在Web應(yīng)用程序中可能存在著,那么對(duì)于一個(gè)攻擊者來(lái)說(shuō)是很容易檢測(cè)到的,然后就可以利用它。很顯然,即使SQL注入錯(cuò)誤并不是開(kāi)發(fā)人員最經(jīng)常犯的錯(cuò)誤,它們也很容易被發(fā)現(xiàn)和利用。

 

對(duì)SQL注入的剖析

這里我們給出一個(gè)SQL注入的例子來(lái)說(shuō)明兩個(gè)問(wèn)題,一是SQL注入這種錯(cuò)誤是很容易犯的,二是只要進(jìn)行嚴(yán)格的程序設(shè)計(jì),這種錯(cuò)誤是很容易預(yù)防的。

這個(gè)示例用的Web應(yīng)用程序包含一個(gè)名為SQLInjection.ASPx簡(jiǎn)單的客戶搜索頁(yè)面,這個(gè)頁(yè)面易于受到SQL注入攻擊。此頁(yè)面包含一個(gè)CompanyName的輸入服務(wù)器控件,還有一個(gè)數(shù)據(jù)表格控件,用于顯示從微軟的示例數(shù)據(jù)庫(kù)Northwind的搜索結(jié)果(這個(gè)數(shù)據(jù)庫(kù)可從SQL Server 2005中找到)。在搜索期間執(zhí)行的這個(gè)查詢包含一個(gè)應(yīng)用程序設(shè)計(jì)中很普通的錯(cuò)誤:它動(dòng)態(tài)地從用戶提供的輸入中生成查詢。這是Web應(yīng)用程序數(shù)據(jù)訪問(wèn)中的一個(gè)主要的錯(cuò)誤,因?yàn)檫@樣實(shí)際上潛在地相信了用戶輸入,并直接將其發(fā)送給你的服務(wù)器。在從“搜索”的單擊事件啟動(dòng)時(shí),這個(gè)查詢看起來(lái)是這個(gè)樣子:

 

protected void btnSearch_Click(object sender, EventArgs e)            {      String cmd = "SELECT [CustomerID], [CompanyName], [ContactName]            FROM [Customers] WHERE CompanyName ='" + txtCompanyName.Text            + "'";            SqlDataSource1.SelectCommand = cmd;            GridView1.Visible = true;            }

在這種情況下,如果一個(gè)用戶輸入“Ernst Handel”作為公司名,并單擊“搜索”按鈕,作為響應(yīng)屏幕會(huì)向用戶顯示那個(gè)公司的記錄,這正是我們所期望的理想情況。不過(guò)一個(gè)攻擊者可以輕易地操縱這個(gè)動(dòng)態(tài)查詢。例如,攻擊者通過(guò)插入一個(gè)UNION子句,并用一個(gè)注釋符號(hào)終止這個(gè)語(yǔ)句的剩余部分。換句話說(shuō),攻擊者不是輸入“Ernst Handel”,而是輸入如下的內(nèi)容:

 

Ernst Handel' UNION SELECT CustomerID, ShipName, ShipAddress            FROM ORDERS--

其結(jié)果是這個(gè)SQL語(yǔ)句在服務(wù)器端執(zhí)行,由于添加了這個(gè)惡意的請(qǐng)求。它會(huì)將這個(gè)動(dòng)態(tài)的SQL查詢轉(zhuǎn)換為下面的樣子:

 

SELECT [CustomerID], [CompanyName],            [ContactName]            FROM [Customers]            WHERE CompanyName ='Ernst Handel'            UNION SELECT CustomerID, ShipName,            ShipAddress            FROM ORDERS--'

這是一個(gè)相當(dāng)合法的SQL語(yǔ)句,它可以在應(yīng)用程序數(shù)據(jù)庫(kù)上執(zhí)行,返回order表中所有的客戶,這些客戶通過(guò)應(yīng)用程序已經(jīng)處理了定單。

典型的SQL防護(hù)

可以看出,在你的應(yīng)用程序中創(chuàng)造并利用一個(gè)SQL注入漏洞是多么容易。幸運(yùn)的是,如前所述,只需要采取幾項(xiàng)簡(jiǎn)單的對(duì)策通常就可以預(yù)防SQL注入攻擊。最常用的、成本效率最高的預(yù)防SQL注入攻擊的方法是驗(yàn)證應(yīng)用程序中所有的最終用于數(shù)據(jù)訪問(wèn)的數(shù)據(jù)輸入。用戶發(fā)出的任何輸入,不管是通過(guò)Web應(yīng)用程序輸入的或者是常駐于數(shù)據(jù)存儲(chǔ)設(shè)備的,都要在服務(wù)器處理你的數(shù)據(jù)訪問(wèn)命令之前在服務(wù)器端驗(yàn)證其類型、長(zhǎng)度、格式和范圍。不幸的是,基于代碼的對(duì)策并不十分安全,而且有可能失敗,特別是當(dāng)發(fā)生如下情況時(shí):

驗(yàn)證程序設(shè)計(jì)不當(dāng)

驗(yàn)證僅在客戶層面執(zhí)行

應(yīng)用程序中,驗(yàn)證時(shí)遺漏了字段(有時(shí)即使是一個(gè)字段)。

防止SQL注入的另外一層涉及正確地確定應(yīng)用程序中所有SQL查詢的參數(shù),不管是在動(dòng)態(tài)SQL語(yǔ)句中還是在存儲(chǔ)過(guò)程中。例如,如果代碼像下面這樣構(gòu)建查詢,就比較安全:

 

SELECT [CustomerID], [CompanyName], [ContactName]            FROM [Customers]            WHERE CompanyName = @CompanyName

當(dāng)作為SQL語(yǔ)句的一部分執(zhí)行時(shí),參數(shù)化查詢將輸入作為一個(gè)字面值,因此服務(wù)器就可能將帶參數(shù)的輸入作為可執(zhí)行代碼。即使你使用了存儲(chǔ)過(guò)程,你仍然必須采取另外一步來(lái)確定輸入的參數(shù),因?yàn)?a href=/pingce/cunchu/ target=_blank class=infotextkey>存儲(chǔ)過(guò)程并不對(duì)嵌入式查詢中的SQL注入提供保護(hù)。

即使采取這上述的簡(jiǎn)單修正措施,SQL注入對(duì)許多公司來(lái)說(shuō)仍然是一個(gè)大問(wèn)題。對(duì)開(kāi)發(fā)團(tuán)隊(duì)的挑戰(zhàn)是要教育每一個(gè)開(kāi)發(fā)人員謹(jǐn)慎對(duì)待這些類型的漏洞,采取有目的的和有效的安全標(biāo)準(zhǔn)來(lái)防止攻擊,增強(qiáng)標(biāo)準(zhǔn)和操作安全的評(píng)估, 確認(rèn)無(wú)任何疏漏。這樣就會(huì)需要引入許多變量去保證應(yīng)用程序安全,因此如果你選擇一項(xiàng)能夠使SQL注入式攻擊成為不可能的數(shù)據(jù)訪問(wèn)技術(shù),你的效率將會(huì)更高。這正是LINQ發(fā)揮作用之所在

LINQ概述

LINQ增加了用任何類型的數(shù)據(jù)存儲(chǔ)進(jìn)行查詢和更新數(shù)據(jù)的標(biāo)準(zhǔn)模式,無(wú)論是SQL數(shù)據(jù)庫(kù)還是XML文檔,還是.NET對(duì)象都是這樣。在構(gòu)建數(shù)據(jù)庫(kù)驅(qū)動(dòng)的應(yīng)用程序時(shí),LINQ能夠使開(kāi)發(fā)人員像管理C#或者VB中的對(duì)象那樣管理相關(guān)數(shù)據(jù),這稱為“LINQ to SQL”,被看作是ADO.NET數(shù)據(jù)技術(shù)系統(tǒng)的一部分。在最初以CTP形式引入時(shí),LINQ to SQL被認(rèn)為是DLINQ。

LINQ to SQL使得你將應(yīng)用程序中的數(shù)據(jù)作為你所使用的編程語(yǔ)言中的本地對(duì)象,簡(jiǎn)化相關(guān)數(shù)據(jù)管理和數(shù)據(jù)庫(kù)連接的復(fù)雜性。事實(shí)上,你可以通過(guò)LINQ顯示和操作數(shù)據(jù)庫(kù)的數(shù)據(jù),而無(wú)需你編寫(xiě)任何SQL語(yǔ)句。在運(yùn)行時(shí)刻,LINQ to SQL將嵌入或“集成”到你的代碼中的查詢轉(zhuǎn)換成SQL,并在數(shù)據(jù)庫(kù)系統(tǒng)上執(zhí)行它們。LINQ to SQL以對(duì)象的形式將查詢結(jié)果返回到應(yīng)用程序中,完全轉(zhuǎn)移了你與數(shù)據(jù)庫(kù)及SQL的交互形式。沒(méi)有什么清除Web應(yīng)用程序中的SQL注入的方法能夠比從應(yīng)用程序中清除SQL更快。??縇INQ to SQL,你就可以實(shí)現(xiàn)。

保障LINQ數(shù)據(jù)庫(kù)存取的安全

LINQ to SQL在專用于數(shù)據(jù)存取時(shí),清除了SQL注入存在于你的應(yīng)用程序中的可能性,原因很簡(jiǎn)單:LINQ代表你執(zhí)行的每次查詢都加上了具體的參數(shù)。在LINQ從你植入的查詢語(yǔ)句中構(gòu)建SQL查詢時(shí),無(wú)論源自何處,提交給查詢的任何輸入都被當(dāng)作字面值。而且,通過(guò)IntelliSense和編譯時(shí)的語(yǔ)法檢查,LINQ與Visual Studio Orcas的集成可以幫助開(kāi)發(fā)人員構(gòu)建合法的查詢。編譯器可以捕捉大量的對(duì)查詢的錯(cuò)誤使用,這些錯(cuò)誤使用可以將功能上的缺陷或其它類型的漏洞帶入到你的應(yīng)用程序中。與此不同的是,在你獲知它正確與否之前,你編寫(xiě)的SQL語(yǔ)句只在運(yùn)行時(shí)刻在數(shù)據(jù)庫(kù)系統(tǒng)上解析。針對(duì)LINQ to SQL的唯一攻擊途徑是攻擊者欺騙LINQ形成非法的或無(wú)意識(shí)的SQL。幸運(yùn)的是,語(yǔ)言和編譯器就是設(shè)計(jì)來(lái)保護(hù)這個(gè)方面的。

在清楚了上述的基本思想后,下面我們就展示應(yīng)該如何運(yùn)用LINQ to SQL防護(hù)SQL注入式攻擊,并具體討論一個(gè)客戶搜索的例子。第一步是創(chuàng)建數(shù)據(jù)庫(kù)中有關(guān)數(shù)據(jù)的對(duì)象模型。Visual Studio Orcas包含一個(gè)新的對(duì)象關(guān)系設(shè)計(jì)器(Object Relational Designer),這個(gè)設(shè)計(jì)器使你能夠生成一個(gè)完全的對(duì)象模型。為了為我們的Northwind Customers表構(gòu)建一個(gè)對(duì)象模型,你通過(guò)選擇“增加新項(xiàng)目…”并選擇“LINQ to SQL File”模板(這個(gè)模板是在對(duì)象關(guān)系設(shè)計(jì)器中打開(kāi)的),在應(yīng)用程序中創(chuàng)建一個(gè)LINQ to SQL的數(shù)據(jù)庫(kù)。為了給 Customers表自動(dòng)構(gòu)建完全的對(duì)象模型,在服務(wù)器資源管理器 (Server Explorer)中選擇這個(gè)表,并將它拖到對(duì)象關(guān)系設(shè)計(jì)器的設(shè)計(jì)層面上。在這個(gè)例子中,對(duì)象關(guān)系設(shè)計(jì)器增加了一個(gè)名為Customers.designer.cs的文件,這個(gè)文件以代碼的形式定義了你將要使用的類,而不是編寫(xiě)代碼直接與數(shù)據(jù)庫(kù)進(jìn)行交互。

在為Customers表中的數(shù)據(jù)定義了對(duì)象模型的類之后中,你可以為客戶的數(shù)據(jù)搜索頁(yè)面直接以代碼的形式查詢數(shù)據(jù)。LINQ-powered 頁(yè)面(LINQtoSQL.ASPx.cs)的Page_Load方法,具體展現(xiàn)了由對(duì)象關(guān)系設(shè)計(jì)器創(chuàng)建的CustomersDataContext類,重新使用了前面在SQLInjection.ASPx頁(yè)面中使用的連接字符串。下面的LINQ查詢重新使用了與where子句匹配的Customer對(duì)象的集合。

 

protected void Page_Load(object sender, EventArgs e)            {            string connectionString =            ConfigurationManager.ConnectionStrings            ["northwndConnectionString1"].ConnectionString;            CustomersDataContext db = new            CustomersDataContext(connectionString);            GridView1.DataSource =            from customer in db.Customers            where customer.CompanyName ==            txtCompanyName.Text            orderby customer.CompanyName            select customer;            GridView1.DataBind();            }

在使用了LINQ to SQL之后,如果我們將“Ernst Handel”作為搜索值,由LINQ在運(yùn)行時(shí)生成并在服務(wù)器上執(zhí)行的SQL語(yǔ)句看起來(lái)將會(huì)是如下這個(gè)樣子:

 

SELECT [t0].[CustomerID], [t0].[CompanyName],            [t0].[ContactName], [t0].[ContactTitle], [t0].[Address],            [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Country],            [t0].[Phone], [t0].[Fax]            FROM [dbo].[Customers] AS [t0]            WHERE [t0].[CompanyName] = @p0            ORDER BY [t0].[CompanyName]}

可以看出,WHERE子句自動(dòng)被加上了參數(shù),因此,用傳統(tǒng)的SQL注入式攻擊是無(wú)法造成破壞的。不管用戶將什么值作為輸入提交給搜索頁(yè)面,這個(gè)查詢是安全的,它不允許用戶的輸入執(zhí)行服務(wù)器上的命令。如果你輸入了前面例子中用來(lái)實(shí)施SQL注入攻擊的字符串,查詢并不會(huì)返回任何信息。事實(shí)上,一個(gè)用戶用這個(gè)查詢可以進(jìn)行的最大的破壞是執(zhí)行一次強(qiáng)力攻擊(或稱蠻力攻擊(Brute force attack)),主要通過(guò)使用搜索功能窮舉Customers表中所有公司的記錄,其使用的方法是猜測(cè)每一個(gè)可能的值。不過(guò),即使這樣也只提供了那個(gè)頁(yè)面上所暴露的Customers表中的值,并不會(huì)給攻擊者注入命令的機(jī)會(huì),這里的命令指的是訪問(wèn)數(shù)據(jù)庫(kù)中額外的數(shù)據(jù)表的命令。

LINQ與安全

正如前面的例子所顯示的那樣,在Web應(yīng)用程序中引入SQL注入漏洞是很容易的,不過(guò)采用適當(dāng)?shù)姆椒ㄒ踩菀仔拚@些漏洞。但是,沒(méi)有什么方法天生就能防止開(kāi)發(fā)人員犯這些簡(jiǎn)單的但卻是危險(xiǎn)的錯(cuò)誤。然而,微軟的LINQ to SQL技術(shù)通過(guò)讓開(kāi)發(fā)人員直接與對(duì)象模型交互而不是直接與數(shù)據(jù)庫(kù)交互,消除了來(lái)自數(shù)據(jù)庫(kù)應(yīng)用程序的SQL注入攻擊的可能性。內(nèi)建于c#和Visual Basic的 LINQ基礎(chǔ)結(jié)構(gòu)關(guān)注正確地表述合法而安全的SQL語(yǔ)句,可以防止SQL注入攻擊,并使開(kāi)發(fā)人員專注于對(duì)他們來(lái)說(shuō)最自然的程序設(shè)計(jì)語(yǔ)言。不管你是將LINQ to SQL用作新的.NET應(yīng)用程序開(kāi)發(fā)的一部分,還是對(duì)它進(jìn)行花樣翻新,用于現(xiàn)有的實(shí)際應(yīng)用程序的數(shù)據(jù)訪問(wèn),你都是作了一個(gè)構(gòu)建更安全的應(yīng)用程序的選擇。

it知識(shí)庫(kù)使用LINQ解除SQL注入安全問(wèn)題,轉(zhuǎn)載需保留來(lái)源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 永济市| 定安县| 黄平县| 宿松县| 仁怀市| 东阿县| 平远县| 甘谷县| 凌源市| 金山区| 简阳市| 新巴尔虎右旗| 禄劝| 祥云县| 德江县| 武穴市| 荔浦县| 拜泉县| 香港 | 竹溪县| 仁化县| 阿荣旗| 吉隆县| 南汇区| 通海县| 郧西县| 花莲市| 阜新市| 夏津县| 汉川市| 博白县| 汉寿县| 唐海县| 高淳县| 遂川县| 苍南县| 都兰县| 准格尔旗| 平顺县| 许昌市| 阿拉善左旗|