##SQL注入簡介:
所謂SQL注入,就是通過把SQL命令插入到Web表單提交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令。具體來說,它是利用現有應用程序,將(惡意)的SQL命令注入到后臺數據庫引擎執行的能力,它可以通過在Web表單中輸入(惡意)SQL語句得到一個存在安全漏洞的網站上的數據庫,而不是按照設計者意圖去執行SQL語句。
## SQL注入方法:
### 一、拼接字符串(通過輸入框輸入SQL語句使其改變原意)
`Select * from T_User where UserID =’txtUserID.Text’andPassword=’ txtPassword.Text ’ `
其原理是通過查找T_User 表中的用戶名(UserID) 和密碼(Password) 的結果來進行授權訪問, 在txtUserID.Text為mysql,txtPassword.Text為mary,那么SQL查詢語句就為:
Select * from users where username =’ mysql ’ and ?password ?=’ mary ’
如果分別給txtUserID.Text 和txtPassword.Text賦值’ or ‘1’ = ‘1’ --和abc。那么,SQL 腳本解釋器中的上述語句就會變為:
Select * from T_User ?where UserID =’’or ?‘1’ = ‘1’ ?-- and Password =’abc’
該語句中進行了兩個條件判斷,只要一個條件成立,就會執行成功。而'1'='1'在邏輯判斷上是恒成立的,后面的"--" 表示注釋,即后面所有的語句為注釋語句這樣我們就成功登錄。即SQL注入成功.
原來SQL語句:`insert ?into ?category(name) ?values(‘”+caName+”’) `
輸入框中輸入`:caName=娛樂新聞’)select category --‘) `
SQL語句變成:`insert ?into ?category(name) values(‘娛樂新聞’)Select ?category ?--‘) `
SQL語句改變后,將執行插入和查詢兩個操作(如果修改的不是查詢而是刪除將會更加可怕),即SQL注入成功。
###二、查看錯誤頁信息(SQL Server有一些系統變量,如果我們沒有限制錯誤信息的輸出,那么注入著可以直接從出錯信息獲取)
Web中的網址:http://www.xxx.com/Login.aspx?id=49 and user>0首先,前面的語句是正常的,重點在and user>0,我們知道,user是SQL Server的一個內置變量,它的值是當前連接的用戶名?,類型為nvarchar。拿一個nvarchar的值跟int的數0比較,系統會先試圖將nvarchar的值轉成int型,當然,轉的過程中肯定會出錯,SQL Server的出錯提示是:將nvarchar值 ”abc” 轉換數據類型?為 int 的列時發生語法錯誤,abc正是變量user的值,這樣,注入著就拿到了數據庫的用戶名,即SQL注入成功。
## SQL注入防范:
### 一、簡單防范:
1.輸入框中限制特殊字符以及長度
2.Web中設置錯誤提示頁即:
在Web.Config文件中設置
~~~
<!--出現錯誤的時候自動導向("~/error.html"是彈出頁面的路徑)-->
? ? ? ? ? <customErrors mode="On" defaultRedirect ="~/error.html" ></customErrors>
~~~
3.URL重寫:
URL重寫就是首先獲得一個進入的URL請求然后把它重新寫成網站可以處理的另一個URL的過程。舉個例子來說,如果通過瀏覽器進來的URL是“UserProfile.aspx?ID=1”那么它可以被重寫成“UserProfile/1.aspx”
### 二、SQL語句中的防范
1.參數化查詢:參數化查詢(Parameterized Query 或 Parameterized Statement)是指在設計與數據庫鏈接并訪問數據時,在需要填入數值或數據的地方,使用參數 (Parameter) 來給值。
例如:
不使用參數化查詢:
`string sql = "select * from comment where newsId = "txtnewsId" order by createTime desc"; `
因為上面SQL語句中的"txtnewsId"是不確定的,每次調用的時候需要將SQL語句重新編譯,這就能用上面的拼接字符串實現SQL注入。
使用參數化查詢:
~~~
string sql = "select * from comment where newsId = @newsId order by createTime desc";
SqlParameter[] paras = new SqlParameter[]{new SqlParameter ("@newsId",newsId)};
~~~
因為上面SQL語句是固定的,調用的時候只需要將@newsId的值傳上去就可以,所以即便用戶輸入任何信息也會當成一個值傳遞進去,防止SQL注入。
2.通過寫存儲過程:
其實在存儲過程里面也需要用到參數化查詢并且存儲過程本身沒有SQL注入這兩點同時滿足才能防止SQL注入。
3.限制數據庫的訪問權限:
設立不同用戶的特殊權限,例如:用戶名為1的用戶只允許查詢操作,然而用戶1的信息被盜取登陸之后就不能對表進行別的操作,這樣就一定程度上保證了數據的安全性。