91网首页-91网页版-91网在线观看-91网站免费观看-91网站永久视频-91网站在线播放

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開(kāi)發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

如何有效防范SQL注入-來(lái)自微軟

admin
2011年1月31日 1:7 本文熱度 3630

SQL 注入是一種攻擊方式,在這種攻擊方式中,惡意代碼被插入到字符串中,然后將該字符串傳遞到 SQL Server 的實(shí)例以進(jìn)行分析和執(zhí)行。任何構(gòu)成 SQL 語(yǔ)句的過(guò)程都應(yīng)進(jìn)行注入漏洞檢查,因?yàn)?SQL Server 將執(zhí)行其接收到的所有語(yǔ)法有效的查詢(xún)。一個(gè)有經(jīng)驗(yàn)的、堅(jiān)定的攻擊者甚至可以操作參數(shù)化數(shù)據(jù)。


SQL 注入的主要形式包括直接將代碼插入到與 SQL 命令串聯(lián)在一起并使其得以執(zhí)行的用戶(hù)輸入變量。一種間接的攻擊會(huì)將惡意代碼注入要在表中存儲(chǔ)或作為元數(shù)據(jù)存儲(chǔ)的字符串。在存儲(chǔ)的字符串隨后串連到一個(gè)動(dòng)態(tài) SQL 命令中時(shí),將執(zhí)行該惡意代碼。


注入過(guò)程的工作方式是提前終止文本字符串,然后追加一個(gè)新的命令。由于插入的命令可能在執(zhí)行前追加其他字符串,因此攻擊者將用注釋標(biāo)記“--”來(lái)終止注入的字符串。執(zhí)行時(shí),此后的文本將被忽略。


以下腳本顯示了一個(gè)簡(jiǎn)單的 SQL 注入。此腳本通過(guò)串聯(lián)硬編碼字符串和用戶(hù)輸入的字符串而生成一個(gè) SQL 查詢(xún):



var Shipcity;
ShipCity = Request.form ("ShipCity");
var sql = "select * from OrdersTable where ShipCity = '" + ShipCity + "'";

用戶(hù)將被提示輸入一個(gè)市縣名稱(chēng)。如果用戶(hù)輸入 Redmond,則查詢(xún)將由與下面內(nèi)容相似的腳本組成:


SELECT * FROM OrdersTable WHERE ShipCity = 'Redmond'


但是,假定用戶(hù)輸入以下內(nèi)容:


Redmond'; drop table OrdersTable--


此時(shí),腳本將組成以下查詢(xún):


SELECT * FROM OrdersTable WHERE ShipCity = 'Redmond';drop table OrdersTable--'


分號(hào) (;) 表示一個(gè)查詢(xún)的結(jié)束和另一個(gè)查詢(xún)的開(kāi)始。雙連字符 (--) 指示當(dāng)前行余下的部分是一個(gè)注釋?zhuān)瑧?yīng)該忽略。如果修改后的代碼語(yǔ)法正確,則服務(wù)器將執(zhí)行該代碼。SQL Server 處理該語(yǔ)句時(shí),SQL Server 將首先選擇 OrdersTable 中的所有記錄(其中 ShipCityRedmond)。然后,SQL Server 將刪除 OrdersTable。


只要注入的 SQL 代碼語(yǔ)法正確,便無(wú)法采用編程方式來(lái)檢測(cè)篡改。因此,必須驗(yàn)證所有用戶(hù)輸入,并仔細(xì)檢查在您所用的服務(wù)器中執(zhí)行構(gòu)造 SQL 命令的代碼。本主題中的以下各部分說(shuō)明了編寫(xiě)代碼的最佳做法。



 驗(yàn)證所有輸入



始終通過(guò)測(cè)試類(lèi)型、長(zhǎng)度、格式和范圍來(lái)驗(yàn)證用戶(hù)輸入。實(shí)現(xiàn)對(duì)惡意輸入的預(yù)防時(shí),請(qǐng)注意應(yīng)用程序的體系結(jié)構(gòu)和部署方案。請(qǐng)記住,為在安全環(huán)境下運(yùn)行而設(shè)計(jì)的程序可能被復(fù)制到不安全的環(huán)境中。以下建議應(yīng)被視為最佳做法:



  • 對(duì)應(yīng)用程序接收的數(shù)據(jù)不做任何有關(guān)大小、類(lèi)型或內(nèi)容的假設(shè)。例如,您應(yīng)該進(jìn)行以下評(píng)估:


    • 如果一個(gè)用戶(hù)在需要郵政編碼的位置無(wú)意中或惡意地輸入了一個(gè) 10 MB 的 MPEG 文件,應(yīng)用程序會(huì)做出什么反應(yīng)?

    • 如果在文本字段中嵌入了一個(gè) DROP TABLE 語(yǔ)句,應(yīng)用程序會(huì)做出什么反應(yīng)?

  • 測(cè)試輸入的大小和數(shù)據(jù)類(lèi)型,強(qiáng)制執(zhí)行適當(dāng)?shù)南拗?。這有助于防止有意造成的緩沖區(qū)溢出。

  • 測(cè)試字符串變量的內(nèi)容,只接受所需的值。拒絕包含二進(jìn)制數(shù)據(jù)、轉(zhuǎn)義序列和注釋字符的輸入內(nèi)容。這有助于防止腳本注入,防止某些緩沖區(qū)溢出攻擊。

  • 使用 XML 文檔時(shí),根據(jù)數(shù)據(jù)的架構(gòu)對(duì)輸入的所有數(shù)據(jù)進(jìn)行驗(yàn)證。

  • 絕不直接使用用戶(hù)輸入內(nèi)容來(lái)生成 Transact-SQL 語(yǔ)句。

  • 使用存儲(chǔ)過(guò)程來(lái)驗(yàn)證用戶(hù)輸入。

  • 在多層環(huán)境中,所有數(shù)據(jù)都應(yīng)該在驗(yàn)證之后才允許進(jìn)入可信區(qū)域。未通過(guò)驗(yàn)證過(guò)程的數(shù)據(jù)應(yīng)被拒絕,并向前一層返回一個(gè)錯(cuò)誤。

  • 實(shí)現(xiàn)多層驗(yàn)證。對(duì)無(wú)目的的惡意用戶(hù)采取的預(yù)防措施對(duì)堅(jiān)定的攻擊者可能無(wú)效。更好的做法是在用戶(hù)界面和所有跨信任邊界的后續(xù)點(diǎn)上驗(yàn)證輸入。
    例如,在客戶(hù)端應(yīng)用程序中驗(yàn)證數(shù)據(jù)可以防止簡(jiǎn)單的腳本注入。但是,如果下一層假設(shè)其輸入已被驗(yàn)證,則任何可以跳過(guò)客戶(hù)端的惡意用戶(hù)就可能不受限制地訪問(wèn)系統(tǒng)。

  • 絕不串聯(lián)未驗(yàn)證的用戶(hù)輸入。字符串串聯(lián)是腳本注入的主要輸入點(diǎn)。

  • 在可能據(jù)以構(gòu)造文件名的字段中,不接受下列字符串:AUX、CLOCK$、COM1 到 COM8、CON、CONFIG$、LPT1 到 LPT8、NUL 以及 PRN。

如果可能,拒絕包含以下字符的輸入。






















輸入字符 在 Transact-SQL 中的含義

;


查詢(xún)分隔符。


'


字符數(shù)據(jù)字符串分隔符。


--


注釋分隔符。


/* ... */


注釋分隔符。服務(wù)器不對(duì) /* 和 */ 之間的注釋進(jìn)行處理。


Xp_


用于目錄擴(kuò)展存儲(chǔ)過(guò)程的名稱(chēng)的開(kāi)頭,如 xp_cmdshell。


使用類(lèi)型安全的 SQL 參數(shù)



SQL Server 中的 Parameters 集合提供了類(lèi)型檢查和長(zhǎng)度驗(yàn)證。如果使用 Parameters 集合,則輸入將被視為文字值而不是可執(zhí)行代碼。使用 Parameters 集合的另一個(gè)好處是可以強(qiáng)制執(zhí)行類(lèi)型和長(zhǎng)度檢查。范圍以外的值將觸發(fā)異常。以下代碼段顯示了如何使用 Parameters 集合:



SqlDataAdapter myCommand = new SqlDataAdapter("AuthorLogin", conn);
myCommand.SelectCommand.CommandType = CommandType.StoredProcedure;
SqlParameter parm = myCommand.SelectCommand.Parameters.Add("@au_id",
SqlDbType.VarChar, 11);
parm.Value = Login.Text;

在此示例中,@au_id 參數(shù)被視為文字值而不是可執(zhí)行代碼。將對(duì)此值進(jìn)行類(lèi)型和長(zhǎng)度檢查。如果 @au_id 值不符合指定的類(lèi)型和長(zhǎng)度約束,則將引發(fā)異常。


在存儲(chǔ)過(guò)程中使用參數(shù)化輸入



存儲(chǔ)過(guò)程如果使用未篩選的輸入,則可能容易受 SQL 注入攻擊。例如,以下代碼容易受到攻擊:



SqlDataAdapter myCommand =
new SqlDataAdapter("LoginStoredProcedure '" +
Login.Text + "'", conn);

如果使用存儲(chǔ)過(guò)程,則應(yīng)使用參數(shù)作為存儲(chǔ)過(guò)程的輸入。


在動(dòng)態(tài) SQL 中使用參數(shù)集合



如果不能使用存儲(chǔ)過(guò)程,您仍可使用參數(shù),如以下代碼示例所示:



SqlDataAdapter myCommand = new SqlDataAdapter(
"SELECT au_lname, au_fname FROM Authors WHERE au_id = @au_id", conn);
SQLParameter parm = myCommand.SelectCommand.Parameters.Add("@au_id",
SqlDbType.VarChar, 11);
Parm.Value = Login.Text;

篩選輸入



篩選輸入可以刪除轉(zhuǎn)義符,這也可能有助于防止 SQL 注入。但由于可引起問(wèn)題的字符數(shù)量很大,因此這并不是一種可靠的防護(hù)方法。以下示例可搜索字符串分隔符。



private string SafeSqlLiteral(string inputSQL)
{
return inputSQL.Replace("'", "''");
}

LIKE 子句



請(qǐng)注意,如果要使用 LIKE 子句,還必須對(duì)通配符字符進(jìn)行轉(zhuǎn)義:



s = s.Replace("[", "[[]");
s = s.Replace("%", "[%]");
s = s.Replace("_", "[_]");


 在代碼中檢查 SQL 注入



應(yīng)檢查所有調(diào)用 EXECUTE、EXEC 或 sp_executesql 的代碼??梢允褂妙?lèi)似如下的查詢(xún)來(lái)幫助您標(biāo)識(shí)包含這些語(yǔ)句的過(guò)程。


SELECT object_Name(id) FROM syscomments


WHERE UPPER(text) LIKE '%EXECUTE (%'


OR UPPER(text) LIKE '%EXECUTE (%'


OR UPPER(text) LIKE '%EXECUTE (%'


OR UPPER(text) LIKE '%EXECUTE (%'


OR UPPER(text) LIKE '%EXEC (%'


OR UPPER(text) LIKE '%EXEC (%'


OR UPPER(text) LIKE '%EXEC (%'


OR UPPER(text) LIKE '%EXEC (%'


OR UPPER(text) LIKE '%SP_EXECUTESQL%'


使用 QUOTENAME() 和 REPLACE() 包裝參數(shù)



在選擇的每個(gè)存儲(chǔ)過(guò)程中,驗(yàn)證是否對(duì)動(dòng)態(tài) Transact-SQL 中使用的所有變量都進(jìn)行了正確處理。來(lái)自存儲(chǔ)過(guò)程的輸入?yún)?shù)的數(shù)據(jù)或從表中讀取的數(shù)據(jù)應(yīng)包裝在 QUOTENAME() 或 REPLACE() 中。請(qǐng)記住,傳遞給 QUOTENAME() 的 @variable 值的數(shù)據(jù)類(lèi)型為 sysname,且最大長(zhǎng)度為 128 個(gè)字符。
















@variable 建議的包裝

安全對(duì)象的名稱(chēng)


QUOTENAME(@variable)


字符串 ≤ 128 個(gè)字符


QUOTENAME(@variable, '''')


字符串 > 128 個(gè)字符


REPLACE(@variable,'''', '''''')


使用此方法時(shí),可對(duì) SET 語(yǔ)句進(jìn)行如下修改:


--Before:


SET @temp = N'select * from authors where au_lname='''


+ @au_lname + N''''


--After:


SET @temp = N'select * from authors where au_lname='''


+ REPLACE(@au_lname,'''','''''') + N''''


由數(shù)據(jù)截?cái)鄦⒂玫淖⑷?/H3>

如果分配給變量的任何動(dòng)態(tài) Transact-SQL 比為該變量分配的緩沖區(qū)大,那么它將被截?cái)唷H绻粽吣軌蛲ㄟ^(guò)將意外長(zhǎng)度的字符串傳遞給存儲(chǔ)過(guò)程來(lái)強(qiáng)制執(zhí)行語(yǔ)句截?cái)?,則該攻擊者可以操作該結(jié)果。例如,以下腳本創(chuàng)建的存儲(chǔ)過(guò)程容易受到由截?cái)鄦⒂玫淖⑷牍簟?/P>

CREATE PROCEDURE sp_MySetPassword


@loginname sysname,


@old sysname,


@new sysname


AS


-- Declare variable.


-- Note that the buffer here is only 200 characters long.


DECLARE @command varchar(200)


-- Construct the dynamic Transact-SQL.


-- In the following statement, we need a total of 154 characters


-- to set the password of 'sa'.


-- 26 for UPDATE statement, 16 for WHERE clause, 4 for 'sa', and 2 for


-- quotation marks surrounded by QUOTENAME(@loginname):


-- 200 – 26 – 16 – 4 – 2 = 154.


-- But because @new is declared as a sysname, this variable can only hold


-- 128 characters.


-- We can overcome this by passing some single quotation marks in @new.


SET @command= 'update Users set password=' + QUOTENAME(@new, '''') + ' where username=' + QUOTENAME(@loginname, '''') + ' AND password = ' + QUOTENAME(@old, '''')


 


-- Execute the command.


EXEC (@command)


GO


通過(guò)向 128 個(gè)字符的緩沖區(qū)傳遞 154 個(gè)字符,攻擊者便可以在不知道舊密碼的情況下為 sa 設(shè)置新密碼。


EXEC sp_MySetPassword 'sa', 'dummy', '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012'''''''''''''''''''''''''''''''''''''''''''''''''''


因此,應(yīng)對(duì)命令變量使用較大的緩沖區(qū),或直接在 EXECUTE 語(yǔ)句內(nèi)執(zhí)行動(dòng)態(tài) Transact-SQL。


使用 QUOTENAME(@variable, '''') 和 REPLACE() 時(shí)的截?cái)?/H3>

如果 QUOTENAME() 和 REPLACE() 返回的字符串超過(guò)了分配的空間,該字符串將被自動(dòng)截?cái)?。以下示例中?chuàng)建的存儲(chǔ)過(guò)程顯示了可能出現(xiàn)的情況。


CREATE PROCEDURE sp_MySetPassword


@loginname sysname,


@old sysname,


@new sysname


AS


 


-- Declare variables.


DECLARE @login sysname


DECLARE @newpassword sysname


DECLARE @oldpassword sysname


DECLARE @command varchar(2000)


 


-- In the following statements, the data stored in temp variables


-- will be truncated because the buffer size of @login, @oldpassword,


-- and @newpassword is only 128 characters, but QUOTENAME() can return


-- up to 258 characters.


 


SET @login = QUOTENAME(@loginname, '''')


SET @oldpassword = QUOTENAME(@old, '''')


SET @newpassword = QUOTENAME(@new, '''')


 


-- Construct the dynamic Transact-SQL.


-- If @new contains 128 characters, then @newpassword will be '123... n


-- where n is the 127th character.


-- Because the string returned by QUOTENAME() will be truncated,


-- it can be made to look like the following statement:


-- UPDATE Users SET password ='1234. . .[127] WHERE username=' -- other stuff here



SET @command = 'UPDATE Users set password = ' + @newpassword


+ ' where username =' + @login + ' AND password = ' + @oldpassword;


 


-- Execute the command.


EXEC (@command)


GO


因此,以下語(yǔ)句將把所有用戶(hù)的密碼都設(shè)置為在前面的代碼中傳遞的值。


EXEC sp_MyProc '--', 'dummy', '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678'


使用 REPLACE() 時(shí),可以通過(guò)超出分配的緩沖區(qū)空間來(lái)強(qiáng)迫字符串截?cái)?。以下示例中?chuàng)建的存儲(chǔ)過(guò)程顯示了可能出現(xiàn)的情況。


CREATE PROCEDURE sp_MySetPassword


@loginname sysname,


@old sysname,


@new sysname


AS


-- Declare variables.


DECLARE @login sysname


DECLARE @newpassword sysname


DECLARE @oldpassword sysname


DECLARE @command varchar(2000)


-- In the following statements, data will be truncated because


-- the buffers allocated for @login, @oldpassword and @newpassword


-- can hold only 128 characters, but QUOTENAME() can return


-- up to 258 characters.


 


SET @login = REPLACE(@loginname, '''', '''''')


SET @oldpassword = REPLACE(@old, '''', '''''')


SET @newpassword = REPLACE(@new, '''', '''''')


 


-- Construct the dynamic Transact-SQL.


-- If @new contains 128 characters, @newpassword will be '123...n


-- where n is the 127th character.


-- Because the string returned by QUOTENAME() will be truncated, it


-- can be made to look like the following statement:


-- UPDATE Users SET password='1234…[127] WHERE username=' -- other stuff here


 


SET @command= 'update Users set password = ''' + @newpassword + ''' where username='''


+ @login + ''' AND password = ''' + @oldpassword + '''';


 


-- Execute the command.


EXEC (@command)


GO


與 QUOTENAME() 一樣,可以通過(guò)聲明對(duì)所有情況都足夠大的臨時(shí)變量來(lái)避免由 REPLACE() 引起的字符串截?cái)唷?yīng)盡可能直接在動(dòng)態(tài) Transact-SQL 內(nèi)調(diào)用 QUOTENAME() 或 REPLACE()?;蛘?,也可以按如下方式計(jì)算所需的緩沖區(qū)大小。對(duì)于 @outbuffer = QUOTENAME(@input),@outbuffer 的大小應(yīng)為 2*(len(@input)+1). 。使用 REPLACE() 和雙引號(hào)時(shí)(如上一示例),大小為 2*len(@input) 的緩沖區(qū)便已足夠。


以下計(jì)算涵蓋所有情況:


While len(@find_string) > 0, required buffer size =


round(len(@input)/len(@find_string),0) * len(@new_string)


+ (len(@input) % len(@find_string))


使用 QUOTENAME(@variable, ']') 時(shí)的截?cái)?/H3>

當(dāng) SQL Server 安全對(duì)象的名稱(chēng)被傳遞給使用 QUOTENAME(@variable, ']') 形式的語(yǔ)句時(shí),可能發(fā)生截?cái)唷R韵麓a顯示了這一可能性。


CREATE PROCEDURE sp_MyProc


@schemaname sysname,


@tablename sysname,


AS


 


-- Declare a variable as sysname. The variable will be 128 characters.


-- But @objectname actually must accommodate 2*258+1 characters.


DECLARE @objectname sysname


SET @objectname = QUOTENAME(@schemaname)+'.'+ QUOTENAME(@tablename)


 


-- Do some operations.


GO


當(dāng)您串聯(lián) sysname 類(lèi)型的值時(shí),應(yīng)使用足夠大的臨時(shí)變量來(lái)保存每個(gè)值的最多 128 個(gè)字符。應(yīng)盡可能直接在動(dòng)態(tài) Transact-SQL 內(nèi)調(diào)用 QUOTENAME()?;蛘撸部梢园瓷弦徊糠炙鰜?lái)計(jì)算所需的緩沖區(qū)大小。


該文章在 2011/1/31 1:07:43 編輯過(guò)

全部評(píng)論5

admin
2011年1月31日 1:8
所謂SQL注入式攻擊,就是攻擊者把SQL命令插入到Web表單的輸入域或頁(yè)面請(qǐng)求的查詢(xún)字符串,欺騙服務(wù)器執(zhí)行惡意的SQL命令。在某些表單中,用戶(hù)輸入的內(nèi)容直接用來(lái)構(gòu)造(或者影響)動(dòng)態(tài)SQL命令,或作為存儲(chǔ)過(guò)程的輸入?yún)?shù),這類(lèi)表單特別容易受到SQL注入式攻擊。常見(jiàn)的SQL注入式攻擊過(guò)程類(lèi)如:   ⑴ 某個(gè)ASP.NET Web應(yīng)用有一個(gè)登錄頁(yè)面,這個(gè)登錄頁(yè)面控制著用戶(hù)是否有權(quán)訪問(wèn)應(yīng)用,它要求用戶(hù)輸入一個(gè)名稱(chēng)和密碼。  ?、?登錄頁(yè)面中輸入的內(nèi)容將直接用來(lái)構(gòu)造動(dòng)態(tài)的SQL命令,或者直接用作存儲(chǔ)過(guò)程的參數(shù)。下面是ASP.NET應(yīng)用構(gòu)造查詢(xún)的一個(gè)例子:   System.Text.StringBuilder query = new System.Text.StringBuilder("SELECT * from Users WHERE login = ’")。Append(txtLogin.Text)。Append("’ AND password=’")。Append(txtPassword.Text)。Append("’");  ?、?攻擊者在用戶(hù)名字和密碼輸入框中輸入"’或’1’=’1"之類(lèi)的內(nèi)容。  ?、?用戶(hù)輸入的內(nèi)容提交給服務(wù)器之后,服務(wù)器運(yùn)行上面的ASP.NET代碼構(gòu)造出查詢(xún)用戶(hù)的SQL命令,但由于攻擊者輸入的內(nèi)容非常特殊,所以最后得到的SQL命令變成:SELECT * from Users WHERE login = ’’ or ’1’=’1’ AND password = ’’ or ’1’=’1’.  ?、?服務(wù)器執(zhí)行查詢(xún)或存儲(chǔ)過(guò)程,將用戶(hù)輸入的身份信息和服務(wù)器中保存的身份信息進(jìn)行對(duì)比。  ?、?由于SQL命令實(shí)際上已被注入式攻擊修改,已經(jīng)不能真正驗(yàn)證用戶(hù)身份,所以系統(tǒng)會(huì)錯(cuò)誤地授權(quán)給攻擊者。   如果攻擊者知道應(yīng)用會(huì)將表單中輸入的內(nèi)容直接用于驗(yàn)證身份的查詢(xún),他就會(huì)嘗試輸入某些特殊的SQL字符串篡改查詢(xún)改變其原來(lái)的功能,欺騙系統(tǒng)授予訪問(wèn)權(quán)限。   系統(tǒng)環(huán)境不同,攻擊者可能造成的損害也不同,這主要由應(yīng)用訪問(wèn)數(shù)據(jù)庫(kù)的安全權(quán)限決定。如果用戶(hù)的帳戶(hù)具有管理員或其他比較高級(jí)的權(quán)限,攻擊者就可能對(duì)數(shù)據(jù)庫(kù)的表執(zhí)行各種他想要做的操作,包括添加、刪除或更新數(shù)據(jù),甚至可能直接刪除表。   二、如何防范?   好在要防止ASP.NET應(yīng)用被SQL注入式攻擊闖入并不是一件特別困難的事情,只要在利用表單輸入的內(nèi)容構(gòu)造SQL命令之前,把所有輸入內(nèi)容過(guò)濾一番就可以了。過(guò)濾輸入內(nèi)容可以按多種方式進(jìn)行。  ?、?對(duì)于動(dòng)態(tài)構(gòu)造SQL查詢(xún)的場(chǎng)合,可以使用下面的技術(shù):   第一:替換單引號(hào),即把所有單獨(dú)出現(xiàn)的單引號(hào)改成兩個(gè)單引號(hào),防止攻擊者修改SQL命令的含義。再來(lái)看前面的例子,“SELECT * from Users WHERE login = ’’’ or ’’1’’=’’1’ AND password = ’’’ or ’’1’’=’’1’”顯然會(huì)得到與“SELECT * from Users WHERE login = ’’ or ’1’=’1’ AND password = ’’ or ’1’=’1’”不同的結(jié)果。   第二:刪除用戶(hù)輸入內(nèi)容中的所有連字符,防止攻擊者構(gòu)造出類(lèi)如“SELECT * from Users WHERE login = ’mas’ —— AND password =’’”之類(lèi)的查詢(xún),因?yàn)檫@類(lèi)查詢(xún)的后半部分已經(jīng)被注釋掉,不再有效,攻擊者只要知道一個(gè)合法的用戶(hù)登錄名稱(chēng),根本不需要知道用戶(hù)的密碼就可以順利獲得訪問(wèn)權(quán)限。   第三:對(duì)于用來(lái)執(zhí)行查詢(xún)的數(shù)據(jù)庫(kù)帳戶(hù),限制其權(quán)限。用不同的用戶(hù)帳戶(hù)執(zhí)行查詢(xún)、插入、更新、刪除操作。由于隔離了不同帳戶(hù)可執(zhí)行的操作,因而也就防止了原本用于執(zhí)行SELECT命令的地方卻被用于執(zhí)行INSERT、UPDATE或DELETE命令。   ⑵ 用存儲(chǔ)過(guò)程來(lái)執(zhí)行所有的查詢(xún)。SQL參數(shù)的傳遞方式將防止攻擊者利用單引號(hào)和連字符實(shí)施攻擊。此外,它還使得數(shù)據(jù)庫(kù)權(quán)限可以限制到只允許特定的存儲(chǔ)過(guò)程執(zhí)行,所有的用戶(hù)輸入必須遵從被調(diào)用的存儲(chǔ)過(guò)程的安全上下文,這樣就很難再發(fā)生注入式攻擊了。  ?、?限制表單或查詢(xún)字符串輸入的長(zhǎng)度。如果用戶(hù)的登錄名字最多只有10個(gè)字符,那么不要認(rèn)可表單中輸入的10個(gè)以上的字符,這將大大增加攻擊者在SQL命令中插入有害代碼的難度。  ?、?檢查用戶(hù)輸入的合法性,確信輸入的內(nèi)容只包含合法的數(shù)據(jù)。數(shù)據(jù)檢查應(yīng)當(dāng)在客戶(hù)端和服務(wù)器端都執(zhí)行——之所以要執(zhí)行服務(wù)器端驗(yàn)證,是為了彌補(bǔ)客戶(hù)端驗(yàn)證機(jī)制脆弱的安全性。   在客戶(hù)端,攻擊者完全有可能獲得網(wǎng)頁(yè)的源代碼,修改驗(yàn)證合法性的腳本(或者直接刪除腳本),然后將非法內(nèi)容通過(guò)修改后的表單提交給服務(wù)器。因此,要保證驗(yàn)證操作確實(shí)已經(jīng)執(zhí)行,唯一的辦法就是在服務(wù)器端也執(zhí)行驗(yàn)證。你可以使用許多內(nèi)建的驗(yàn)證對(duì)象,例如RegularExpressionValidator,它們能夠自動(dòng)生成驗(yàn)證用的客戶(hù)端腳本,當(dāng)然你也可以插入服務(wù)器端的方法調(diào)用。如果找不到現(xiàn)成的驗(yàn)證對(duì)象,你可以通過(guò)CustomValidator自己創(chuàng)建一個(gè)。  ?、?將用戶(hù)登錄名稱(chēng)、密碼等數(shù)據(jù)加密保存。加密用戶(hù)輸入的數(shù)據(jù),然后再將它與數(shù)據(jù)庫(kù)中保存的數(shù)據(jù)比較,這相當(dāng)于對(duì)用戶(hù)輸入   的數(shù)據(jù)進(jìn)行了“消毒”處理,用戶(hù)輸入的數(shù)據(jù)不再對(duì)數(shù)據(jù)庫(kù)有任何特殊的意義,從而也就防止了攻擊者注入SQL命令。 System.Web.Security.FormsAuthentication類(lèi)有一個(gè) HashPasswordForStoringInConfigFile,非常適合于對(duì)輸入數(shù)據(jù)進(jìn)行消毒處理。  ?、?檢查提取數(shù)據(jù)的查詢(xún)所返回的記錄數(shù)量。如果程序只要求返回一個(gè)記錄,但實(shí)際返回的記錄卻超過(guò)一行,那就當(dāng)作出錯(cuò)處理。

該評(píng)論在 2011/1/31 1:08:09 編輯過(guò)
admin
2011年1月31日 1:8
sql注入就是,通過(guò)語(yǔ)句的連接做一些不是你想要的操作.. 舉個(gè)例子你就懂了 例如你要查詢(xún)id=1的記錄,直接連接就是這樣"select * from tableName where id=1" 別人可以寫(xiě)成"select * from tableName where id=1;delete from tableName" 這樣就把你的表數(shù)據(jù)全部刪除了.就是加個(gè);繼續(xù)寫(xiě)腳本,當(dāng)然,這只是個(gè)例子..還能做其他操作, 比如獲取你數(shù)據(jù)庫(kù)的用戶(hù)名,密碼什么的,那就慘了,,傳參的方式可以防止注入 "select * from tableName where id=@id" 然后給@id賦值,就ok啦.. 這是我的個(gè)人看法,,期待更好的解答

該評(píng)論在 2011/1/31 1:08:27 編輯過(guò)
admin
2011年1月31日 1:9
在conn.asp中添加代碼: 
<%
dim sql_injdata,SQL_inj,SQL_Get,SQL_Data,Sql_Post
SQL_injdata = "'│and│exec│insert│select│delete│update│count│*│%│chr│mid│master│truncate│char│declare"
SQL_inj = split(SQL_Injdata,"│")
If Request.QueryString<>"" Then
For Each SQL_Get In Request.QueryString
For SQL_Data=0 To Ubound(SQL_inj)
if instr(Request.QueryString(SQL_Get),Sql_Inj(Sql_DATA))>0 Then
Response.Write "<Script Language=javascript>alert('注意:請(qǐng)不要提交非法請(qǐng)求!');history.back(-1)</Script>"
Response.end
end if
next
Next
End If
If Request.Form<>"" Then
For Each Sql_Post In Request.Form
For SQL_Data=0 To Ubound(SQL_inj)
if instr(Request.Form(Sql_Post),Sql_Inj(Sql_DATA))>0 Then
Response.Write "<Script Language=javascript>alert('注意:請(qǐng)不要提交非法請(qǐng)求!');history.back(-1)</Script>"
Response.end
end if
next
next
end if
%>

該評(píng)論在 2011/1/31 1:10:09 編輯過(guò)
admin
2011年1月31日 1:28

防止SQL病毒注入都有那些好方法呢?附加點(diǎn)代碼,謝謝了!

在你接收url參數(shù)的時(shí)候 過(guò)濾特殊字符就可以了 veryeasy~~ 
給你一個(gè)函數(shù)
'_______________________________________________________________
'函數(shù)名:SetRequest
'作 用:防止SQL注入
'ParaName:參數(shù)名稱(chēng)-字符型
'ParaType:參數(shù)類(lèi)型-數(shù)字型(1表示是數(shù)字,0表示為字符)
'RequestType:請(qǐng)求方式(0:直接請(qǐng)求,1:Request請(qǐng)求,2:post請(qǐng)求,3:get請(qǐng)求,4:Cookies請(qǐng)求,5:WEB請(qǐng)求)
'_______________________________________________________________
Public Function SetRequest(ParaName,RequestType,ParaType)
Dim ParaValue
Select Case RequestType
Case 0
ParaValue=ParaName
Case 1
ParaValue=Request(ParaName)
Case 2
ParaValue=Request.Form(ParaName)
Case 3
ParaValue=Request.QueryString(ParaName)
Case 4
ParaValue=Request.Cookies(ParaName)
Case 5
ParaValue=Request.ServerVariables(ParaName)
End Select

If ParaType=1 Then
If instr(ParaValue,",")>0 Then
If not isNumeric(Replace(Replace(ParaValue,",","")," ","")) Then
Response.Redirect("/")
End If
Else
If not isNumeric(ParaValue) Then
Response.Redirect("/")
End If
End If
Else
ParaValue=Replace(Replace(ParaValue,Chr(0),""),"'","")
End If
SetRequest=ParaValue
End function


接收參數(shù)的時(shí)候 全部用 SetRequest(參數(shù)) 就可以了

該評(píng)論在 2011/1/31 1:29:22 編輯過(guò)
admin
2011年1月31日 1:35
在.NET中,如何防止sql注入了? 最好的方法是什么了 首先 你需要在客戶(hù)端盡量的限制非法字符 可以用正則表達(dá)式 再次 你需要在sql語(yǔ)句中限制 如果是C#的話(huà) 可以再SQL字符串前面加@ 最后 盡量使用存儲(chǔ)過(guò)程而少用SQL語(yǔ)句 這樣基本就差不多了 再能被注入就是高手了 那個(gè)防不勝防

該評(píng)論在 2011/1/31 1:35:05 編輯過(guò)
關(guān)鍵字查詢(xún)
相關(guān)文章
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專(zhuān)業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車(chē)隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開(kāi)發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類(lèi)企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉(cāng)儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷(xiāo)售管理,采購(gòu)管理,倉(cāng)儲(chǔ)管理,倉(cāng)庫(kù)管理,保質(zhì)期管理,貨位管理,庫(kù)位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶(hù)的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

主站蜘蛛池模板: 日韩高清在线观看 | 制服丝袜诱惑在线 | 日韩AⅤ美女AⅤ视 | 国产精品一区不卡在 | 国产一区二区三区 | 日韩欧美视频免费看 | 欧洲一级视频在 | 欧美日韩国产在线人 | 日韩一级大片亚洲 | 欧美在线一区二区 | 精品三级乱伦免费 | 91官网在线观看 | 老牛色导航 | 美日韩在线观看 | 国产精品秘在线观看 | 日韩一级在线视频 | 国产日韩欧美911 | 国产精品日韩精品 | 欧美日韩精品久 | 午夜国产精品看片 | 97日韩在线 | 国产妇女视频免费 | 国产日韩在线观看 | 国产老妇伦 | 乱伦免费影视亚洲 | 三级成人影院 | 激情婷婷| 无码精品久久久久久人妻中字 | 91精品秘入口观看 | 成人亚洲欧美 | 91丨九色丨熟女在 | 日本成本人片免 | 日韩h片在线观看 | 日韩97在线| 国产精品香焦免费看 | 精品国产综合色在线 | 国产香蕉尹人在线 | 成人福利免费视频 | 国产精品自拍喷水 | 日韩一级视频免费 | 日本色色的视频一区 |