標籤:
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
我們的解決方式是:
1、首先在UI錄入時,要控制資料的類型和長度、防止SQL注入式攻擊,系統提供檢測注入式攻擊的函數,一旦檢測出注入式攻擊,該資料即不能提交;
2、商務邏輯層控制,通過在方法內部將SQL關鍵字用一定的方法屏蔽掉,然後檢查資料長度,保證提交SQL時,不會有SQL資料庫注入式攻擊代碼;但是這樣處理後,要求UI輸出時將屏蔽的字元還原。因此系統提供屏蔽字元 的函數和還原字元的函數。
3、在資料訪問層,絕大多數採用預存程序訪問資料,調用時以預存程序參數的方式訪問,也會很好的防止注入式攻擊。
淺談C#.NET防止SQL注入式攻擊