#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
try12
{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
catch25
{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
try42
{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
catch72
{73
// 错误处理: 处理用户提交信息!74
}75
}76
#endregion77

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
try110
{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
catch124
{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
try141
{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
catch153
{154
return "";155
}156
return outputstring;157
}158
#endregion
我们的解决方式是:
1、首先在UI录入时,要控制数据的类型和长度、防止SQL注入式攻击,系统提供检测注入式攻击的函数,一旦检测出注入式攻击,该数据即不能提交;
2、业务逻辑层控制,通过在方法内部将SQL关键字用一定的方法屏蔽掉,然后检查数据长度,保证提交SQL时,不会有SQL数据库注入式攻击代码;但是这样处理后,要求UI输出时将屏蔽的字符还原。因此系统提供屏蔽字符 的函数和还原字符的函数。
3、在数据访问层,绝大多数采用存储过程访问数据,调用时以存储过程参数的方式访问,也会很好的防止注入式攻击。


