/// 移除字符串中的可能引起危险Sql字符
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string RemoveSqlUnsafeString(string str)
{
string p = @"[-|;|,|\/|\(|\)|\[|\]|\}|\{|%|@|\*|!|\']";
return Regex.Replace(str, p, "");
}
/// <summary>
/// 检测是否有Sql危险字符
/// </summary>
/// <param name="str">要判断字符串</param>
/// <returns>判断结果</returns>
public static bool IsSafeSqlString(string str)
{
return !Regex.IsMatch(str, @"[-|;|,|\/|\(|\)|\[|\]|\}|\{|%|@|\*|!|\']");
}
/// <summary>
/// 替换sql语句中的有问题符号
/// </summary>
public static string ChkSQL(string str)
{
string str2;
if (str == null)
{
str2 = "";
}
else
{
str = str.Replace("'", "''");
str2 = str;
}
return str2;
}
#region 过滤攻击性字符
/// <summary>
/// 过滤攻击性字符
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string ReplaceBadChar(string str)
{
if (!string.IsNullOrEmpty(str))
{
str = Regex.Replace(str, @"(?s)/\*.*?\*/", "", RegexOptions.IgnoreCase); //删除注释:/* */
str = Regex.Replace(str, @"(?s)<script.*?>.*?</script>", "", RegexOptions.IgnoreCase); //删除脚本
str = Regex.Replace(str, @"(?s)<style.*?>.*?</style>", "", RegexOptions.IgnoreCase); //需要把用户自己添加的样式都删除
//<link href="/scripts/PopBox/stylesheets/Styles.css" rel="stylesheet" type="text/css" />
str = Regex.Replace(str, @"(?s)<link[^>]+href+([^>]+?)>", "", RegexOptions.IgnoreCase);
//替换一些比较特殊的字符
// str = str.Replace(" ", " "); //将 替换为一个空格
str = str.Replace("—", "-");//将—替换为-
str = str.Replace("”", "”");
str = str.Replace("“", "“");
str = str.Replace("≤", "<=");
str = str.Replace("≠", "!=");
str = str.Replace("≥", ">=");
//<img src="" onerror="" /> <([^>|^<]+?on)([\w]+[^=]+?)=([^>]+?)>
str = Regex.Replace(str, @"<([^>|^<]+?on)([a-z|A-Z]+[^=]+?)=([^>]+?)>", "<$1_$2=$3>", RegexOptions.IgnoreCase);//过滤可能的XSS攻击,脚本事件
//javascript:
str = str.Replace("javascript:", "javascript:");//过滤<img src="javascript:alert(/xss/)" />
str = str.Replace("vbscrript:", "vbscript:");//过滤vbscript
str = str.Replace("script", "script");//过滤所有可能的脚本
//style="XSS:expression(alert(/xss/))"
str = str.Replace("expression", "Expression");//过滤所有可能的脚本
//str=Regex.Replace(str,@"(style(.*))=(.*)(expression)","$1=$3",RegexOptions.IgnoreCase); //过滤样式中,可能带有的脚本事件
//<iframe src=
str = Regex.Replace(str, "(?s)<iframe.*?>.*?</iframe>", "", RegexOptions.IgnoreCase);//过滤Ifrmae;
//防止转码XSS攻击:<img src="javascript:alert('XSS');">
str = str.Replace("#", "#");//过滤#
// str = str.Replace("&", "&");//过滤&
str = str.Replace("%", "%");//过滤%
//<img STYLE="background-image: \75\72\6c\28\6a\61\76\61\73\63\72\69\70\74\3a\61\6c\65\72\74\28\27\58\53\53\27\29\29">
str = str.Replace("\\", "/");//过滤\ 防止连接16进制的攻击
if (str.IndexOf("<script") >= 0)
str = str.Replace("<", "<--script");
if (str.IndexOf("'") > 0)
str = str.Replace("'", "’");
//str = str.Replace("<", "<");
//str = str.Replace(">", ">");
}
return str;
}
#endregion
/// <summary>
/// 正则表达式验证
/// </summary>
/// <param name="pattern">验证表达式</param>
/// <returns>是否匹配成功</returns>
private bool IsPattern(string pattern)
{
return Regex.IsMatch(this._val, pattern, RegexOptions.IgnoreCase);
}
大家存在5点误区:
1、sql注入比较难防,需要替换select,delete等一打字符
其实对于字符型替换再多都没有替换单引号为两个单引号来的好!对于数字型替换再多都没有用,一定要类型转换。
2、忽略DropDownList传来的东西
其实是不对的,一切客户端的东西都是不可信任的,select下拉框也是!因为可以自己做一个htm提交到服务器。
3、access比sqlserver不安全
安全不安全关键看怎么用,如果sqlserver还是像access一样用,一个sa帐户的话,很明显,sqlserver比access不安全,可以直接得到表名和字段名!access反而倒安全点了,因为只能通过逐位猜解得到。
4、网站没有显示出错信息就说明网站是安全的
当有记录的时候显示记录,没有记录的时候显示找不到任何记录,通过这两种状态就可以猜解字段名了,所以网页不出错不能说明是安全的
5、忽略post提交的信息
很多人对url上传递的东西过滤严格,对于post的东西不理不睬是不对的,post的东西更加容易被注入,因为一般字段比较多
在asp.net中强烈建议通过参数来实现sql而不是sql拼接,因为就算你每一个都过滤百密难有疏
比如:
SqlConnection conn=new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["conn"]);
SqlCommand comm=new SqlCommand("update tb1 set vName=@vName,iAge=@iAge where ID=@id",conn);
SqlParameter parm1=new SqlParameter("@vName",SqlDbType.NVarChar,50);
parm1.Value=((TextBox)e.Item.FindControl("name")).Text;
SqlParameter parm2=new SqlParameter("@iAge",SqlDbType.Int);
parm2.Value=((TextBox)e.Item.FindControl("age")).Text;
SqlParameter parm3=new SqlParameter("@id",SqlDbType.Int);
parm3.Value=this.DataGrid1.DataKeys[e.Item.ItemIndex];
comm.Parameters.Add(parm1);
comm.Parameters.Add(parm2);
comm.Parameters.Add(parm3);
conn.Open();
comm.ExecuteNonQuery();
conn.Close();
这样的代码看起来舒服而且又安全,何乐不为?