也谈C#.NET防止SQL注入式攻击

出处:http://www.cnblogs.com/jacky73/archive/2009/09/02/1558770.html

#region 防止sql注入式攻击(可用于UI层控制)

        ///         /// 判断字符串中是否有SQL攻击代码,by fangbo.yu 2008.07.18         ///         /// 传入用户提交数据         /// true-安全;false-有注入攻击现有; public bool ProcessSqlStr(string inputString)         {             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";             try             {                 if ((inputString != null) && (inputString != String.Empty))                 {                     string str_Regex = @"\b(" + SqlStr + @")\b";

                    Regex Regex = new Regex(str_Regex, RegexOptions.IgnoreCase);                     //string s = Regex.Match(inputString).Value;                     if (true == Regex.IsMatch(inputString))                         return false;

                }             }             catch             {                 return false ;             }             return true;         }

        ///         /// 处理用户提交的请求,校验sql注入式攻击,在页面装置时候运行         /// System.Configuration.ConfigurationSettings.AppSettings["ErrorPage"].ToString(); 为用户自定义错误页面提示地址,         /// 在Web.Config文件时里面添加一个 ErrorPage 即可         ///         ///             ///         public void ProcessRequest()         {             try             {                 string getkeys = "";                 string sqlErrorPage = System.Configuration.ConfigurationSettings.AppSettings["ErrorPage"].ToString();                 if (System.Web.HttpContext.Current.Request.QueryString != null)                 {

                    for (int i = 0; i < System.Web.HttpContext.Current.Request.QueryString.Count; i++)                     {                         getkeys = System.Web.HttpContext.Current.Request.QueryString.Keys[i];                         if (!ProcessSqlStr(System.Web.HttpContext.Current.Request.QueryString[getkeys]))                         {                             System.Web.HttpContext.Current.Response.Redirect(sqlErrorPage + "?errmsg=" + getkeys + "有SQL攻击嫌疑!");                             System.Web.HttpContext.Current.Response.End();                         }                     }                 }                 if (System.Web.HttpContext.Current.Request.Form != null)                 {                     for (int i = 0; i < System.Web.HttpContext.Current.Request.Form.Count; i++)                     {                         getkeys = System.Web.HttpContext.Current.Request.Form.Keys[i];                         if (!ProcessSqlStr(System.Web.HttpContext.Current.Request.Form[getkeys]))                         {                             System.Web.HttpContext.Current.Response.Redirect(sqlErrorPage + "?errmsg=" + getkeys + "有SQL攻击嫌疑!");                             System.Web.HttpContext.Current.Response.End();                         }                     }                 }             }             catch             {                 // 错误处理: 处理用户提交信息!             }         }         #endregion

       

        #region 转换sql代码(也防止sql注入式攻击,可以用于业务逻辑层,但要求UI层输入数据时候进行解码)         ///         /// 提取字符固定长度,by fangbo.yu 2008.07.18         ///         ///         ///         ///         public string CheckStringLength(string inputString, Int32 maxLength)         {             if ((inputString != null) && (inputString != String.Empty))             {                 inputString = inputString.Trim();

                if (inputString.Length > maxLength)                     inputString = inputString.Substring(0, maxLength);             }             return inputString;         }

        ///         /// 将输入字符串中的sql敏感字,替换成"[敏感字]",要求输出时,替换回来,by fangbo.yu 2008.07.21         ///         ///         ///         public string MyEncodeInputString(string inputString)         {             //要替换的敏感字             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";             try             {                 if ((inputString != null) && (inputString != String.Empty))                 {                     string str_Regex = @"\b(" + SqlStr + @")\b";                                         Regex Regex = new Regex(str_Regex,RegexOptions.IgnoreCase);                     //string s = Regex.Match(inputString).Value;                     MatchCollection matches = Regex.Matches(inputString);                     for (int i = 0; i < matches.Count; i++)                         inputString = inputString.Replace(matches[i].Value, "[" + matches[i].Value + "]");                                   }             }             catch             {                 return "";             }             return inputString;

        }

        ///         /// 将已经替换成的"[敏感字]",转换回来为"敏感字",by fangbo.yu 2008.07.21         ///         ///         ///         public string MyDecodeOutputString(string outputstring)         {             //要替换的敏感字             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";             try             {                 if ((outputstring != null) && (outputstring != String.Empty))                 {                     string str_Regex = @"\[\b(" + SqlStr + @")\b\]";                     Regex Regex = new Regex(str_Regex,RegexOptions.IgnoreCase);                     MatchCollection matches = Regex.Matches(outputstring);                     for (int i = 0; i < matches.Count; i++)                         outputstring = outputstring.Replace(matches[i].Value, matches[i].Value.Substring(1, matches[i].Value.Length - 2));                                   }             }             catch             {                 return "";             }             return outputstring;         }         #endregion

我们的解决方式是:

1、首先在UI录入时,要控制数据的类型和长度、防止SQL注入式攻击,系统提供检测注入式攻击的函数,一旦检测出注入式攻击,该数据即不能提交; 2、业务逻辑层控制,通过在方法内部将SQL关键字用一定的方法屏蔽掉,然后检查数据长度,保证提交SQL时,不会有SQL数据库注入式攻击代码;但是这样处理后,要求UI输出时将屏蔽的字符还原。因此系统提供屏蔽字符 的函数和还原字符的函数。 3、在数据访问层,绝大多数采用存储过程访问数据,调用时以存储过程参数的方式访问,也会很好的防止注入式攻击。

 

posted on 2012-11-29 15:51  Q&A  阅读(230)  评论(0)    收藏  举报