淺談C#.NET防止SQL注入式攻擊

1#region 防止sql注入式攻擊(可用於UI層控制)
  2
  3/// 
  4/// 判斷字符串中是否有SQL攻擊代碼
  5/// 
  6/// 傳入用戶提交數據
  7/// true-安全;false-有注入攻擊現有;
  8public bool ProcessSqlStr(string inputString)
  9{
 10    string SqlStr = @"and|or|exec|execute|insert|select|delete|update|alter|create|drop|count|\*|chr|char|asc|mid|substring|master|truncate|declare|xp_cmdshell|restore|backup|net +user|net +localgroup +administrators";
 11    try
 12    {
 13        if ((inputString != null) && (inputString != String.Empty))
 14        {
 15            string str_Regex = @"\b(" + SqlStr + @")\b";
 16
 17            Regex Regex = new Regex(str_Regex, RegexOptions.IgnoreCase);
 18            //string s = Regex.Match(inputString).Value; 
 19            if (true == Regex.IsMatch(inputString))
 20                return false;
 21
 22        }
 23    }
 24    catch
 25    {
 26        return false;
 27    }
 28    return true;
 29}
 30
 31
 32/// 
 33/// 處理用戶提交的請求,校驗sql注入式攻擊,在頁面裝置時候運行
 34/// System.Configuration.ConfigurationSettings.AppSettings["ErrorPage"].ToString(); 爲用戶自定義錯誤頁面提示地址,
 35/// 在Web.Config文件時裏面添加一個 ErrorPage 便可
 36/// 
 37///     
 38/// 
 39public void ProcessRequest()
 40{
 41    try
 42    {
 43        string getkeys = "";
 44        string sqlErrorPage = System.Configuration.ConfigurationSettings.AppSettings["ErrorPage"].ToString();
 45        if (System.Web.HttpContext.Current.Request.QueryString != null)
 46        {
 47
 48            for (int i = 0; i < System.Web.HttpContext.Current.Request.QueryString.Count; i++)
 49            {
 50                getkeys = System.Web.HttpContext.Current.Request.QueryString.Keys[i];
 51                if (!ProcessSqlStr(System.Web.HttpContext.Current.Request.QueryString[getkeys]))
 52                {
 53                    System.Web.HttpContext.Current.Response.Redirect(sqlErrorPage + "?errmsg=" + getkeys + "有SQL攻擊嫌疑!");
 54                    System.Web.HttpContext.Current.Response.End();
 55                }
 56            }
 57        }
 58        if (System.Web.HttpContext.Current.Request.Form != null)
 59        {
 60            for (int i = 0; i < System.Web.HttpContext.Current.Request.Form.Count; i++)
 61            {
 62                getkeys = System.Web.HttpContext.Current.Request.Form.Keys[i];
 63                if (!ProcessSqlStr(System.Web.HttpContext.Current.Request.Form[getkeys]))
 64                {
 65                    System.Web.HttpContext.Current.Response.Redirect(sqlErrorPage + "?errmsg=" + getkeys + "有SQL攻擊嫌疑!");
 66                    System.Web.HttpContext.Current.Response.End();
 67                }
 68            }
 69        }
 70    }
 71    catch
 72    {
 73        // 錯誤處理: 處理用戶提交信息!
 74    }
 75}
 76#endregion
 77
 78
 79
 80
 81#region 轉換sql代碼(也防止sql注入式攻擊,能夠用於業務邏輯層,但要求UI層輸入數據時候進行解碼)
 82/// 
 83/// 提取字符固定長度
 84/// 
 85/// 
 86/// 
 87/// 
 88public string CheckStringLength(string inputString, Int32 maxLength)
 89{
 90    if ((inputString != null) && (inputString != String.Empty))
 91    {
 92        inputString = inputString.Trim();
 93
 94        if (inputString.Length > maxLength)
 95            inputString = inputString.Substring(0, maxLength);
 96    }
 97    return inputString;
 98}
 99
100/// 
101/// 將輸入字符串中的sql敏感字,替換成"[敏感字]",要求輸出時,替換回來
102/// 
103/// 
104/// 
105public string MyEncodeInputString(string inputString)
106{
107    //要替換的敏感字
108    string SqlStr = @"and|or|exec|execute|insert|select|delete|update|alter|create|drop|count|\*|chr|char|asc|mid|substring|master|truncate|declare|xp_cmdshell|restore|backup|net +user|net +localgroup +administrators";
109    try
110    {
111        if ((inputString != null) && (inputString != String.Empty))
112        {
113            string str_Regex = @"\b(" + SqlStr + @")\b";
114
115            Regex Regex = new Regex(str_Regex, RegexOptions.IgnoreCase);
116            //string s = Regex.Match(inputString).Value; 
117            MatchCollection matches = Regex.Matches(inputString);
118            for (int i = 0; i < matches.Count; i++)
119                inputString = inputString.Replace(matches[i].Value, "[" + matches[i].Value + "]");
120
121        }
122    }
123    catch
124    {
125        return "";
126    }
127    return inputString;
128
129}
130
131/// 
132/// 將已經替換成的"[敏感字]",轉換回來爲"敏感字"
133/// 
134/// 
135/// 
136public string MyDecodeOutputString(string outputstring)
137{
138    //要替換的敏感字
139    string SqlStr = @"and|or|exec|execute|insert|select|delete|update|alter|create|drop|count|\*|chr|char|asc|mid|substring|master|truncate|declare|xp_cmdshell|restore|backup|net +user|net +localgroup +administrators";
140    try
141    {
142        if ((outputstring != null) && (outputstring != String.Empty))
143        {
144            string str_Regex = @"\[\b(" + SqlStr + @")\b\]";
145            Regex Regex = new Regex(str_Regex, RegexOptions.IgnoreCase);
146            MatchCollection matches = Regex.Matches(outputstring);
147            for (int i = 0; i < matches.Count; i++)
148                outputstring = outputstring.Replace(matches[i].Value, matches[i].Value.Substring(1, matches[i].Value.Length - 2));
149
150        }
151    }
152    catch
153    {
154        return "";
155    }
156    return outputstring;
157}
158#endregion
sql

咱們的解決方式是:
一、首先在UI錄入時,要控制數據的類型和長度、防止SQL注入式攻擊,系統提供檢測注入式攻擊的函數,一旦檢測出注入式攻擊,該數據即不能提交;
二、業務邏輯層控制,經過在方法內部將SQL關鍵字用必定的方法屏蔽掉,而後檢查數據長度,保證提交SQL時,不會有SQL數據庫注入式攻擊代碼;可是這樣處理後,要求UI輸出時將屏蔽的字符還原。所以系統提供屏蔽字符 的函數和還原字符的函數。
三、在數據訪問層,絕大多數採用存儲過程訪問數據,調用時以存儲過程參數的方式訪問,也會很好的防止注入式攻擊。shell

相關文章
相關標籤/搜索