PHP函数用字符代码替换符号以停止SQL注入

时间:2009-06-15 03:07:02

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

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

}

6 个答案:

答案 0 :(得分:11)

你看过mysql_real_escape_string吗?

  

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

答案 1 :(得分:3)

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

答案 2 :(得分:2)

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

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

$converted = strtr($input, $trans);

答案 3 :(得分:1)

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

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

答案 4 :(得分:0)

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

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

更新 显然,mysql _ 界面不支持占位符。这基本上意味着它不安全或不适合任何类型的部署,寻找另一个驱动程序。

答案 5 :(得分: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