依旧是防sql注入问题,因为没有使用存储过程和SqlParameter。逐个修改源文件是很麻烦的事情,我也不知道有什么更好的解决方法,想在Application_BeginRequest中用正则检测GET和POST的字符。
于是来向大家收集下检查SQL注入的C#正则表达式。如果有更好的解决办法推荐最好了,谢谢!!!!!!!

解决方案 »

  1.   

    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using Fish;
    /// <summary>
    /// ProcessRequest 的摘要说明
    /// </summary>
    public class ProcessRequest
    {
    #region SQL注入式攻击代码分析
            /**//// <summary>
            /// 处理用户提交的请求
            /// </summary>
            public void StartProcessRequest()
            {
                try
                {
                    string getkeys = "";
                    string sqlErrorPage = "/";
                    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].ToLower()))
                            {
                                System.Web.HttpContext.Current.Response.Redirect(sqlErrorPage);
                                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].ToLower()))
                    //        {
                    //            System.Web.HttpContext.Current.Response.Redirect (sqlErrorPage);
                    //            System.Web.HttpContext.Current.Response.End();
                    //        }
                    //    }
                    //}            }
                catch
                {
                    common.MessageBox("非法操作,IP已记录", false);
                    common.GoUrl("index.aspx");
                }
            }
            /**//// <summary>
            /// 分析用户请求是否正常
            /// </summary>
            /// <param name="Str">传入用户提交数据</param>
            /// <returns>返回是否含有SQL注入式攻击代码</returns>
            private bool ProcessSqlStr(string Str)
            {
                bool ReturnValue = true;
                try
                {
                    if (Str != "" && Str != null)
                    {
                        string SqlStr = "";
                        if (SqlStr == "" || SqlStr == null)
                        {
                            SqlStr = "'|and|exec|insert|select|delete|update|count|*|chr|mid|master|truncate|char|declare";
                        }
                        string[] anySqlStr = SqlStr.Split('|');
                        foreach (string ss in anySqlStr)
                        {
                            if (Str.IndexOf(ss) >= 0)
                            {
                                ReturnValue = false;
                            }
                        }
                    }
                }
                catch
                {
                    ReturnValue = false;
                }
                return ReturnValue;
            }
            #endregion
    }
      

  2.   

    首先,存储过程并不能防SQL注入!
    自己手工写过滤方法并不能彻底的防范SQL注入!
      

  3.   

    过滤是最蹩脚的做法。DELETE 算不算非法字符?对于大部分的过滤函数都会“过滤”掉它。但是人家是真的需要输入DELETE 呢??如果CSDN 过滤了,那么数据库板块的程序员根本没发发帖子了。
      

  4.   


    能尽量做到最好啊,1楼的会判断错误的。
    哎,能不能出点正则啊,不要讨论该不该防御好不好。
    类似这种:                @"[\s\S]*select[\s|" + zero + @"]+[\S]+[\s" + zero + @"]+from[\s\S]*",
                    @"[\s\S]*insert[\s]+into[\s\S]*",
                    @"[\s\S]*update[\s]+[\S]+[\s]+set[\s\S]*",
                    @"[\s\S]*delete[\s]+from+[\s\S]*",
                    @"[\s\S]*declare[\s]+@[\s\S]*",
                    @"[\S|\s]*[\s|" + zero + @"]or|and+[\s|" + zero + @"]+[\S]+\=[\s\S]*"
      

  5.   

     void Application_BeginRequest(Object sender, EventArgs e)
        {
            StartProcessRequest();    }    #region 
        private void StartProcessRequest()
        {
            try
            {
                string getkeys = "";
                string sqlErrorPage = "index.aspx";
                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);
                            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 (getkeys == "__VIEWSTATE") continue;
                        if (!ProcessSqlStr(System.Web.HttpContext.Current.Request.Form[getkeys]))
                        {
                            System.Web.HttpContext.Current.Response.Redirect(sqlErrorPage);
                            System.Web.HttpContext.Current.Response.End();
                        }
                    }
                }
            }
            catch
            {
                
            }
        }
        private bool ProcessSqlStr(string Str)
        {
            bool ReturnValue = true;
            try
            {
                if (Str.Trim() != "")
                {
                    string SqlStr = "exec¦insert¦select¦delete¦master¦update¦truncate¦declare";
                    string[] anySqlStr = SqlStr.Split('¦');
                    foreach (string ss in anySqlStr)
                    {
                       if(!Str.ToLower().Contains("updatepanel"))
                       {
                        if (Str.ToLower().IndexOf(ss) >= 0)
                        {
                            ReturnValue = false;
                            break;
                        }
                       }
                    }
                }
            }
            catch
            {
                ReturnValue = false;
            }
            return ReturnValue;
        }
    或用的HttpModule 
    参考
      

  6.   

      string SqlStr = "exec¦insert¦select¦delete¦master¦update¦truncate¦declare"; 
    这种容易误判
      

  7.   

    呵呵 ,NqIceCoffee 在一声叹息后发话了。。
      

  8.   

    首先来说,问题本身是不存在什么难度,问题本质在于针对于非法字符边界的定义。
    像这种类型问题只得根据实际的应用场合寻求解决方案。脱离系统边界解决问题的方法显得毫无意义。
    这东西就像是抗生素一样,他可以杀死病毒,但在杀死病毒的同时也把正常细胞弄坏了。
    没有绝对安全的系统,安全级别越高肯定导致的结果就是系统超发难用,他是牺牲用户体验为前提的。
    当然这时有人就会说了,我可以把那东西做的很完美。我承认可以做到,但成本呢,一个专人跟进数月,就研究这所谓的要求级别提升。我想他的实际意义和价值权重只有客户自己才能掂量了。
    我想就这是IE为什么要弄个分级审查的原因吧,因为根据系统的边界来设置安全限制才是最合理的。
    就像一个美食类的论坛,1楼朋友的答案思路就非常好嘛,当然就像7楼朋友所说,如果本是技术站点,那就会显得不合时适,影响正常功能。
    所以就这个问题,楼主需要根据具体的业务场景才能找到相对好用的方案,就这里的朋友给出的任何完善的方案有可能到了你的业务场景反倒成了负作用。
    在这里也写一个,是根据一楼的思路改的。楼主参考一下.        //// <summary>
            /// 分析用户请求是否正常
             /// </summary>
            /// <param name="Str">传入用户提交数据</param>
            /// <returns>返回是否含有SQL注入式攻击代码</returns>
            private bool ProcessSqlStr(string Str)
            {
                bool ReturnValue = true;
                string re = "insert|select|delete|update|%|net\\s+user|xp_cmdshell|/add|exec\\s+master\\.dbo\\.xp_cmdshell|net\\s+localgroup\\s+administrators";
                ReturnValue=System.Text.RegularExpressions.Regex.Match(str, re).Success;
                return ReturnValue;
            }
            #endregion
      

  9.   

    呵呵,symbol441  到底还是来了,只是我回晚了。