1
#region 防止sql注入式攻擊(可用於UI層控制)
2
3
///
4
/// 判斷字符串中是否有SQL攻擊代碼
5
///
6
/// 傳入用戶提交數據
7
/// true-安全;false-有注入攻擊現有;
8
public 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
///
39
public 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
///
88
public 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
///
105
public 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
///
136
public 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、在數據訪問層,絕大多數采用存儲過程訪問數據,調用時以存儲過程參數的方式訪問,也會很好的防止注入式攻擊。
