2

我正在尝试编写一个 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;

}
4

6 回答 6

12

你看过mysql_real_escape_string吗?

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

于 2009-06-15T03:10:19.380 回答
3

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

于 2009-06-15T03:10:21.907 回答
2

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

$entities = array(
    '#' => '&#35;',
    '&' => '&#38;',
    ....
);

$converted = strtr($input, $trans);
于 2009-06-15T03:23:26.943 回答
1

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

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

于 2009-06-15T10:02:07.930 回答
0

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

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

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

于 2009-06-15T03:37:25.630 回答
0

我强烈建议您遵循其他人发布的罐装解决方案,例如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
于 2009-06-15T18:38:53.687 回答