本来对正则表达式不是很了解,但由于项目需要,项目主要没有采用存储过程方式来存储SQL语句,所以很有可能被黑客用SQL注入攻击,现在就在网上找了找解决办法,在业务层来过滤SQL语句,防止SQL注入攻击,主要是采用了正则表达式,因为正则表达式对字符串的操作是很强大的.

首先用一个Validate()类来封装正则表达式和相关操作:

//验证是否有SQL注入字符
private bool ValidateQuery(Hashtable queryConditions)
{
//构造SQL的注入关键字符
#region 字符
string[] strBadChar = {"and"
,"exec"
,"insert"
,"select"
,"delete"
,"update"
,"count"
,"or"
//,"*"
,"%"
,":"
,"/'"
,"/""
,"chr"
,"mid"
,"master"
,"truncate"
,"char"
,"declare"
,"SiteName"
,"net user"
,"xp_cmdshell"
,"/add"
,"exec master.dbo.xp_cmdshell"
,"net localgroup administrators"};
#endregion

//构造正则表达式
string str_Regex = ".*("
for (int i = 0; i < strBadChar.Length - 1; i++)
{
str_Regex += strBadChar[i] + "|"
}
str_Regex += strBadChar[strBadChar.Length - 1] + ").*"
//避免查询条件中_list情况
foreach (string str in queryConditions.Keys)
{
if(str.Substring(str.Length - 5)=="_list")
{
//去掉单引号检验
str_Regex = str_Regex.Replace("|'|", "|");
}
string tempStr = queryConditions[str].ToString();
if (Regex.Matches(tempStr.ToString(), str_Regex).Count > 0)
{
//有SQL注入字符
return true;
}
}
return false;
}

queryConditions 是一个hashtable,用于传入查询条件,hashtable中的键值(key)为:@name,相对应SQL中的参数,那Value则对应为参数的实际值了.

正则表达式的应用主要是按这样的规律来过滤字符串的:

.*(and|exec|select|update|or|'|''|).*   //  str_Regex

核心函数主要是: Regex.Matches(tempStr.ToString(), str_Regex). 

要是在 tempStr 字符串中含有非法字符, 则函数的Count值将大于0

好了,就这样就可以判断是否含有SQL注入攻击字符了.

 

嗯,前面找了一个防止SQL注入的说明,今天下午把它打成一个webSecurityObject类中的静态方法:)

编写思想:
1,输入的SQL查询字符中,不能包括     '+空格的类型(有可能英文会有 Ben3's Diary类型的字符,故要过滤的是 select * from a='1' and 这一类中的分号结束符。
2,输入的SQL查询字符中,不能有单独的查询匹配符及关键字存在,由于SQL的特殊性,一般来说,这些关键字都有一个特性,即关键字一般是通过 空格+关键字+空格 的状态存在的
3,注意HTTPDECODE的状态,即输入的是否是HTTP编码。。。
4,使用正则来实现

源码如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Text.RegularExpressions;
namespace MPWS.BaseCore
{
    public class WebSecurityObject
    {
        public WebSecurityObject()
        {
        }
       
        public static bool IsNumeric(string checkText)
        {
            Regex reg=new Regex(@"^/d$");
            return reg.IsMatch(checkText);
        }
        public static bool CheckSQLString(string checkText,bool NeedUrlCodeCheck)
        {
            string tempString=checkText;
            if (NeedUrlCodeCheck)
                tempString = HttpUtility.UrlDecode(tempString);
            //说明:不能存在'+空格的存在,并且,不能有空格+字符+空格的命令存在
            string sqlString = @"/s*/'/s+|/s(and|exec|insert|select|delete|update|count|/*|/%|chr|mid|master|truncate|char|declare)/s";
            Regex reg=new Regex(sqlString);
            return reg.IsMatch(tempString);
        }
        public static string FormatString(string inText)
        {
            string tempstring = inText;
            tempstring = tempstring.Replace("'", "''");
            return tempstring;
        }
    }
}