日期:2014-05-18  浏览次数:20404 次

(狂散分!!2008年SQL防注入第一帖)SQL防注入解决方案大征集
由于公司网站流量巨大,上次被一无名黑客来探了探路,留下“××到此一游”,虽然没有酿成恶果,但也把Leader吓出一身冷汗。

下面是我昨晚写的的关于URL防SQL注入,先贴为敬。

C# code

        /// <summary>
        /// 检测是否含有危险字符(防止Sql注入)
        /// </summary>
        /// <param name="contents">预检测的内容</param>
        /// <returns>返回True或false</returns>
        private bool HasDangerousContents(string contents)
        {
            bool bReturnValue = false;
            if (contents.Length > 0)
            {
                //convert to lower
                string sLowerStr = contents.ToLower();
                //RegularExpressions
                string sRxStr = @"(\sand\s)|(\sand\s)|(\slike\s)|(select\s)|(insert\s)|(delete\s)|(update\s[\s\S].*\sset)|(create\s)|(\stable)|(<[iframe|/iframe|script|/script])|(')|(\sexec)|(\sdeclare)|(\struncate)|(\smaster)|(\sbackup)|(\smid)|(\scount)";
                //Match
                bool bIsMatch = false;
                System.Text.RegularExpressions.Regex sRx = new System.Text.RegularExpressions.Regex(sRxStr);
                bIsMatch = sRx.IsMatch(sLowerStr, 0);
                if (bIsMatch)
                {
                    bReturnValue = true;
                }
            }
            return bReturnValue;
        }



------解决方案--------------------
不要拼接sql语句直接执行,多使用SqlParameter,SqlCommand
------解决方案--------------------
所有的sql调用全部用存储过程,而且存储过程内部也尽量不要拼接sql语句,这样就能防止injection
------解决方案--------------------
在asp.net中强烈建议通过参数来实现sql而不是sql拼接,因为就算你每一个都过滤百密难有疏 
C# code
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();

------解决方案--------------------
存储过程,要不你就得做字符串过滤,也可以用转换,webservice等!要看个人的经验了!比如xwny.aspx?id=2这样的常被注入的例子你可以在你的方法中mode(int64 id)这样定义不就没事了!
------解决方案--------------------
SqlHelper + 参数化存储过程 + 正则表达式
------解决方案--------------------
这个问题应该转到 SQL 时去, 建议使用SP. 这一点我也很赞同.

但T-SQL 有时间比SP要方便一点, 写好过滤 T-SQL 的方法后,还要做
到以下几点 (人个认为)

1、把所有 TextBox (Input type="text" ) 等输入信息的地方,限制一个最大输入长度。
这样至少可以给输入危险字符带来限制,这还是有点作用的,况且这样做并不难。(JavaScript遍历)

2、楼主也提到过,URL可能也会传输入危险字符。这个解决,你可以用URL重写功能,这样比较好,至少可以增加难度
例如:abc.aspx?year=2008&month=5 可重写为 abc/2008/5 (扩展名是可以隐藏的)

3、把你写的过滤方法及一些防范措施,最好用到 Global 或 http请求 里. (建议Global)

这样应该比较不错。
还有,我想随便问一下楼主,你确认无名的黑客就是SQL注入攻击您的网站的?
或者说你的服务器,本身就是他的一个肉机或别的什么?
------解决方案--------------------
只要先在查询分析器里建好存储过程,我建议最好用视图至于里代码里吗,你多用适配器+SQL参数结合来使用,如有可能再建一个数据封装类来给数据传输加密.
其实防注入还是很简单的!