ENIX.DQ 發表於 2010-7-21 10:34:29

ASP3.0使用Command物件與Parameter連接資料庫

前言:

  SQL Injection(資料隱碼)攻擊,是個常見的網站入侵方法;某種程度上而言,造成這種攻擊生效的漏洞,是coder自己造成的,因為在操作資料庫的SQL語法中使用了"拼湊"的方式來組成所需的SQL語法,因而造成的嚴重漏洞;防堵的方法有很多,像是過濾查詢語句、限縮查詢資料庫帳號的使用權限、使用參數(Paramater)方式進行資料庫操作..等,本文將簡介如何使用ADODB.Command物件搭配Paramater來進行操作資料庫的動作。

使用環境:IIS + ASP 3.0
資料庫:可搭配SQL Server或Access

本文:

  首先介紹如何將原本的SQL 語句變更為使用ADODB.Command物件並配合使用參數來執行
原本的執行方法原始碼如下:
set conn=server.createobject("ADODB.Connection"):conn.open "driver={sql server};database=school;server=127.0.0.1; uid=username;pwd=12345678"
set rs=Server.CreateObject("ADODB.Recordset")
sql="select * from TableName where TID = '"& TID &"' order by StartDate"
rs.open sql,conn,3,3
變換說明:

  第一行set conn保持原樣,第二行可以完全刪除,第三行sql語句的部分,應改為如下的語句sql="select * from TableName where TID = ? order by StartDate"   變更的重點在於,把原本拼湊成的參數,變換成?(半型問號),其餘保持不變,接下來就是加入Adodb.Command物件來執行SQL語句:Set cmd = Server.CreateObject("ADODB.Command")

With cmd
.ActiveConnection= conn
.CommandType=1
.NamedParameters=True
.CommandText=sql
.Parameters.Append .CreateParameter("@TID",2,1,,TID)
end with

set rs=cmd.execute
cmd.cancel
set cmd = nothing其中注意到 .Parameters.Append 這一行的.CreateParameter("@TID",2,1,,TID)
@TID為參數名稱,2表示這個參數使用的DataType是SmallInt(2-Byte),1表示這是個input的參數
第四個空白欄位是用來表示這個參數輸入資料的大小,一般用於DataType為字元類別時使用
最後一個TID就是要輸入的資料,可以是變數,也可以是實際資料

由於這是一個查詢語句,因此我們需要把執行結果丟入一個Adodb.recordset物件,以便之後使用
因此加入了set rs=cmd.execute 這樣的語句,之後就可以用rs("FieldName")這樣的方式,來讀取資料表的內容
接下來兩句,是物件使用後就宣告消滅的一個使用習慣
以下為變更後,完整的程式碼set conn=server.createobject("ADODB.Connection"):conn.open "driver={sql server};database=school;server=127.0.0.1; uid=username;pwd=testpassword"

Set cmd = Server.CreateObject("ADODB.Command")

With cmd
.ActiveConnection= conn
.CommandType=1
.NamedParameters=True
.CommandText=sql
.Parameters.Append .CreateParameter("@TID",2,1,,TID)
end with

set rs=cmd.execute
cmd.cancel
set cmd = nothing以上為SQL語句為Select的使用方法,當使用Update、Insert、Delete做為執行命令時,又有另外一種執行方法

以下將介紹使用Update語法時,使用的方法,底下是完整的語句
set conn=server.createobject("ADODB.Connection"):conn.open "driver={sql server};database=school;server=127.0.0.1; uid=username;pwd=testpassword"

sqlstr = "UPDATE TableName "
sqlstr = sqlstr & " SET ItemNumber = ?,MemberType=?,MemberName=? "
sqlstr = sqlstr & " ,MemberJobList = ?,Other =? "
sqlstr = sqlstr & " WHERE ReportTableID=? AND MemberTableID=? "

Set cmd = Server.CreateObject("ADODB.Command")
With cmd
.ActiveConnection= conn
.CommandType=1
.NamedParameters=True
.CommandText=sqlstr
.Parameters.Append .CreateParameter("@ItemNumber",16,1,,ItemNumber)
.Parameters.Append .CreateParameter("@MemberType",202,1,20,MemberType)
.Parameters.Append .CreateParameter("@MemberName",202,1,50,MemberName)
.Parameters.Append .CreateParameter("@MemberJobList",202,1,500,MemberJobList)
.Parameters.Append .CreateParameter("@Other",202,1,500,Other)
.Parameters.Append .CreateParameter("@ReportTableID",3,1,,ReportTableID)
.Parameters.Append .CreateParameter("@MemberTableID",3,1,,MemberTableID)
end with
cmd.execute howmany
cmd.cancel
set cmd = nothing
conn.close

程式碼說明:

  在這個部分,sqlstr為SQL語句的組成,與使用SELECT語句時相同,把所有原本拼湊變數的地方,全數換成?(半型問號); .Parameters.Append 的部分也是一樣,要針對每個參數使用的內容做個別的設定,須注意參數的加入順序,必須與sqlstr語句中每一個問號相對應,順序錯誤將會造成執行上的問題。

  接著特別注意到cmd.execute howmany這一句,cmd.execute 是執行SQL語句,後面加上howmany可以把執行結果傳回,使用者可以根據讀取howmany獲得一個數值,這個數值代表的是該次執行SQL語句後,有多少筆資料受到影響。

  例如,我們使用的UPDATE語句只會更新一筆資料,那麼執行後,howmany的數值會變為1,如果是0,某種程度上代表著該次執行是失敗的(沒有達到預期的效果)。如此可以用來判斷執行的結果是否順利;當然,不加上howmany,一樣可以執行。至於這一行後面的,就不多敘述了。

  另外關於SQL語句中?(半形問號)的使用,根據瞭解,像是「SET ItemNumber = ?」這樣的語句,可以換成「SET ItemNumber = @ItemNumber」這樣的型態,而在 『.Parameters.Append .CreateParameter("@ItemNumber",16,1,,ItemNumber)』這個部分,就可以透過紅字的地方,做為對應的根據,如此就不需要按照?(問號)的出現順序,做新增參數的動作。(PS:此段文字上未經使用證實)

  以上為介紹在ASP下使用Command物件及Paramater查詢資料庫的方法;搭配Paramater使用可有效防止SQL Injection的攻擊,建議把有遭受SQL Injection攻擊疑慮的ASP程式碼,通通改成此一方式。



參考網頁:
http://www.w3schools.com/ADO/ado_ref_parameter.asp
SQL Injection (資料隱碼)– 駭客的 SQL填空遊戲(上) http://www.microsoft.com/taiwan/sql/SQL_Injection_G1.htm
頁: [1]
查看完整版本: ASP3.0使用Command物件與Parameter連接資料庫