簡單地說,Sql注入就是將Sql代碼傳遞到應用程式的過程,但不是按照應用程式開發人員預定或期望的方式插入,相當大一部分程式員在編寫代碼的時 候,並沒有對使用者輸入資料的合法性進行判斷,使應用程式存在安全隱患。這種漏洞並非系統照成,而是由程式員在編程中忽略了安全因素。Sql注入漏洞攻擊原 理就是利用非法參數獲得敏感資訊,收集整理,分析出管理員帳號密碼。
當開發應用程式時,尤其是有關資料庫資訊的查詢,查詢語句中可能會有拼接字串注入漏洞,這便會導致使用者資料泄露。那麼該如何防範此類漏洞的出現。
可以為查詢語句設定參數,方法執行個體如下面所示:
Using(Sqlconnection cn = new sqlconnection(“連接字串”))
{
cn.open();
using(sqlcommand cmd = cn.creatcommand())
{
cmd.commandtext=”select * from T_table where name=’”+textbox.text+”’”;
(此時如果在文字框中輸入1’ or ‘1’=’1)就可以擷取資料庫資訊。會造成資訊的泄露。解決辦法就是引入參數。方法如下。
cmd.commandtext=”select * from T_table where name=@Name”;
cmd.Parameters.Add (new sqlParameter ("@Name", textbox.text))};
這樣查詢資料就會從資料庫查詢比對,不會再出現注入漏洞攻擊的情況。
}
}
每一次必不可少的會寫對資料庫操作的Sql語句,例如以下驗證登陸的Sql語句:
string strSql="select * from Table Where UserName='"+textBoxUserName.Text+'"and UserPassord='"+textBoxPassword.Text+"'";
或者
string strSql=string.Format("select * from Table where UserName='{0}' and UserPassword='{1}'",textBoxUserName.Text,textBoxPassword.Text);
在上面的語 句中,對資料庫操作的Sql語句使用字串拼接的方式寫的,這種方式是前期的程式員以及初學者通用的對資料庫操作的一種Sql語句寫法,上述代碼中的 textBoxUserName是使用者在textBoxUserName文字框中提交的使用者名稱,textUserpassword是使用者在 textUserpassword文字框中提交的密碼,在理想的狀態下,使用者 為了對系統進行攻擊,使用者(就是駭客)可能嘗試篡改Sql語句,達到登入的目的。例如使用者可能在使用者名稱文字框中輸入下面的語句:
1' or 1=1 --
下面我們把上面一行的語句代入到前面用於登入的Sql語句中,得到下面的Sql語句:
select * from Table where UserId='1' or 1=1 --'and UserName=' '
稍 微學過資料庫Sql語句的,很快就會發現上面一句話的不正常,這條Sql語句會返回Table表的全部資料,這就是駭客有機可乘的地方,駭客可以用這種方 法成功登陸,還可以擷取該Table表的所有資訊。下面解釋一下這句Sql語句:如果只有select * from Table,就會返回該Table表的所有資訊,where後是查詢條件,1=1永遠為True,不管User='1'為True還是為 False,UserId='1' or 1=1 都為True。至於--'and UserName=' ' ,因為兩個連字號(--)是MS Sql Server的注釋標記(My Sql和Oracle資料庫也使用相同的技術,不過My Sql使用的注釋標記師是符號#,Oracle使用的是分號;),--後面的內容傳到資料庫查詢時都被注釋了,那麼--後面的內容就沒用了,Sql語句不 會執行了,所以where後的查詢條件永遠為True,綜上所述,上面的Sql查詢語句會返回Table表的所有資訊!
通過這種Sql文法漏洞,駭客們可以達到他們的目的,但Sql注入漏洞攻擊絕對不止這一種,複雜的還有很多,我不在說了。下面我談一下我知道在.NET中應對上面這種Sql注入攻擊的防範措施。
我 們所能做的,如果不修改上面的Sql查詢語句,那一種方法就是利用TextBox控制項的MaxLength屬性,這樣就鍵入了駭客鍵入字元的數量,從而可 以限制駭客向伺服器發送大量的非法命令,但這種方法只是掩耳盜鈴,治不了根本。第二種方法就是刪除使用者輸入中的單引號,方法是在單引號後面加一個或多個單 引號,或者利用空格替換單引號,這樣就可以預防此類攻擊。但局限性是如果使用者的使用者名稱或密碼中就含有單引號呢,那就不可行了!
最完美的一種方法就是使用ADO.NET Command對象的參數集合, 在前面的可以進行Sql注入漏洞攻擊的Sql語句中,通過使用字串拼接方法動態建立查詢,在這裡我們可以利用ADO.NET Command的對象的Parameters屬性提供的功能,傳遞執行Sql語句所使用的參數,在這種方法中參數名必須以字元@為首碼,例如以下Sql查 詢語句:
string strSql="select * from Table where UserName=@UserName and UserPassword=@UserPassword";
在該語句中,@UserName和@UserPassword就是參數名,可以使用以下語句為該參數傳值:
SqlCommand cmd=new SqlCommand(strSql,conn);
SqlParameters[] pams=new SqlParameters(new SqlParameters("@UserName",textBoxUserName.Text),new SqlParameters("@UserPassword",textBoxPassword.Text));
cmd.Parameters.AddRange(pams);
參數名不區分大小寫,這種方法也適宜預存程序和SqlDataAdapter對象。
我們在動態建立Sql語句中使用了@UserName和@UserPassword名稱,而不是拼接多個字元 串,這樣就可以使用SqlCommand對象的Parameters集合傳遞值,該方法可以安全的建立動態Sql串連。參數在Sql Server內部不是簡單的字串替換,Sql Server直接0用添加的值進行資料比較,因此不會有Sql注入漏洞攻擊。