【问题标题】:PHP Function to replace symbols with character codes to stop SQL InjectionPHP函数用字符代码替换符号以停止SQL注入
【发布时间】:2010-11-02 22:08:20
【问题描述】:

我正在尝试编写一个 php 函数来阻止 MySQL 注入尝试。我正在做的是使用 str_replace() 删除符号并用它们的 HTML 字符代码替换它们。我的问题是代码都包含 但我也想用它们的代码替换这些符号。如何在不将代码更改为以下内容的情况下做到这一点:

&#38&#59;&338&#59;#35&#59;32&#59;

这是我的功能:

function replaceSymbols( $text )
{
   $text = str_replace( '#', '&#35', $text );
   $text = str_replace( '&', '&' $text ); 
   $text = str_replace( ';', '&#59', $text );

   $text = str_replace( ' ', ' ' $text );
   $text = str_replace( '!', '!' $text );
   $text = str_replace( '"', '"' $text );   
   $text = str_replace( '$', '$' $text );
   $text = str_replace( '%', '%' $text );  
   $text = str_replace(  "'" '&#39', $text );
   $text = str_replace( '(', '(' $text );
   $text = str_replace( ')', ')' $text );
   $text = str_replace( '*', '*' $text );   
   $text = str_replace( '+', '&#43', $text );
   $text = str_replace( ',', ',' $text );
   $text = str_replace( '-', '-' $text );
   $text = str_replace( '.', '.' $text );   
   $text = str_replace( '/', '&#47', $text );
   $text = str_replace( ':', ':' $text );   
   $text = str_replace( '<', '&#60;' $text );
   $text = str_replace( '=', '&#61;' $text );
   $text = str_replace( '>', '&#62;' $text );   
   $text = str_replace( '?', '&#63', $text );
   $text = str_replace( '[', '&#91', $text );
   $text = str_replace( '\\', '&#92;' $text );
   $text = str_replace( ']', '&#93;' $text );
   $text = str_replace( '^', '&#94;' $text );   
   $text = str_replace( '_', '&#95', $text );
   $text = str_replace( '`', '&#96', $text );
   $text = str_replace( '{', '&#123;' $text );
   $text = str_replace( '|', '&#124;' $text );   
   $text = str_replace( '}', '&#125', $text );
   $text = str_replace( '~', '&#126', $text );

   return $text;

}

【问题讨论】:

  • 这些字符中的大多数不会增加 SQL 注入的风险。 mysql_real_escape_string() 函数处理所有需要处理的字符。并且该函数知道如何考虑字符集,而您的函数不知道。

标签: php mysql character-encoding sql-injection symbols


【解决方案1】:

你看过mysql_real_escape_string吗?

转义特殊字符 未转义的字符串,考虑到 的当前字符集 连接,以便安全放置 它在 mysql_query() 中。

【讨论】:

  • 当你开始对自己思考“自己,这是一个常见的问题......”时,答案通常是“使用库函数!”这就是他们在那里的原因。您应该假设,除非另有说服力,否则库函数会更好、更快、更安全、更便宜(编码等)。
【解决方案2】:

mysql_real_escape_string($text) 是否有任何原因不能满足您的需求?

【讨论】:

    【解决方案3】:

    其他人提到mysql_real_escape_string() 效果很好。如果您真的想转换为实体,请查看htmlentities()。如果仍然不能转换您想要的所有字符,您也可以像这样使用strtr()

    $entities = array(
        '#' => '&#35;',
        '&' => '&#38;',
        ....
    );
    
    $converted = strtr($input, $trans);
    

    【讨论】:

      【解决方案4】:

      不要试图解决这些基本问题——它们已经解决了。除非您想学习基础知识,但不要在生产环境中使用您的解决方案。通过使用mysql_real_escape_string 或使用参数化查询,解决了查询转义问题,并且它可以工作。自制的解决方案通常具有使它们无用的细微错误或特性。我现在找不到这篇文章,但是在编写恐怖代码时的杰夫阿特伍德(或者是乔尔?)写了一个朋友试图做他自己的 strip_tags 功能......但失败了。最近,加密也是如此:自制软件几乎总是失败。

      您的方法:
      ...不太适合手头的任务,因为经典的字符串转义是完全可逆的,而您的方法是单向函数(与散列无关^^)。

      【讨论】:

        【解决方案5】:

        为什么不使用占位符?任何类型的转义方案都不起作用,因为您忘记了某些内容,或者因为突然想以某种其他格式输出(HTML 字符实体不再起作用)。

        依赖于驱动程序,除了安全之外,您还可以从占位符中获得额外的好处,例如更快的网络传输(数字作为本地整数、浮点数等而不是字符串传输)和解析,使用准备好的语句提高网络速度。

        更新 显然 mysql_ 接口不支持占位符。这基本上意味着它不安全或不适合任何类型的部署,请寻找其他驱动程序。

        【讨论】:

        • FWIW、查询参数的占位符和一般准备好的语句,不被最常见的 PHP 的 MySQL API 支持。
        • ??哇,这太离谱了。很高兴知道。只是出于好奇,为什么人们不直接使用 PDO?
        【解决方案6】:

        我强烈建议您遵循其他人发布的罐头解决方案,例如mysql_real_escape_string()。也就是说,您的功能在关键方面存在缺陷。当您保护某些东西时,您的默认策略应该是默认拒绝。这意味着您假设任何给定的输入或请求都是攻击,然后检查输入,如果您可以确定某些东西肯定不是攻击,则允许它。在您的函数的上下文中,这意味着您检查输入是否在一组已知的、可接受的字符中,并转义其他所有字符。伪代码:

        function replaceSymbols(text):
            result = ""
            for each character c in text:
               if isalpha(c) or isdigit(c):
                   append c to result
               else
                   append escape(c) to result
            return result
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-11-16
          • 1970-01-01
          • 2010-09-09
          • 2016-10-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多