2012-07-25 117 views
0

我们的服务器上今天出现了一个奇怪的问题。 我们已经通过GET请求成功传递了mysql查询中的%和_的DDOS符号。例如cakephp转义函数或mysql_real_escape_string不安全?

domain.com/search/%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25v%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25%25a 

它似乎是cakephp不过滤它们?在official mysql guide他们写了很多这个问题。这是他们展示如何解决这个:

在CakePHP的框架
addcslashes(mysql_real_escape_string(“%something_”), “%_”); 

有功能escape()其使用,随处可见的模型。看看它包含什么:

/** 
* Returns a quoted and escaped string of $data for use in an SQL statement. 
* 
* @param string $data String to be prepared for use in an SQL statement 
* @param string $column The column into which this data will be inserted 
* @param boolean $safe Whether or not numeric data should be handled automagically if no column data is provided 
* @return string Quoted and escaped data 
*/ 
    function value($data, $column = null, $safe = false) { 
     $parent = parent::value($data, $column, $safe); 

     if ($parent != null) { 
      return $parent; 
     } 
     if ($data === null || (is_array($data) && empty($data))) { 
      return 'NULL'; 
     } 
     if ($data === '' && $column !== 'integer' && $column !== 'float' && $column !== 'boolean') { 
      return "''"; 
     } 
     if (empty($column)) { 
      $column = $this->introspectType($data); 
     } 

     switch ($column) { 
      case 'boolean': 
       return $this->boolean((bool)$data); 
      break; 
      case 'integer' : 
      case 'float' : 
      case null : 
       if ($data === '') { 
        return 'NULL'; 
       } 
       if (is_float($data)) {                            
        return str_replace(',', '.', strval($data)); 
       } 
       if ((is_int($data) || is_float($data) || $data === '0') || (
        is_numeric($data) && strpos($data, ',') === false && 
        $data[0] != '0' && strpos($data, 'e') === false)) { 
         return $data; 
        } 
      default: 
       $data = "'" . mysqli_real_escape_string($this->connection, $data) . "'"; 
      break; 
     } 

     return $data; 
    } 

只是一个基本的保护agains一些变量类型和这样的东西。关于MySQL的转义特殊字符什么??大约一年前,我阅读了如何在mysql查询的百分号帮助下逃避报价标志=)当时是盲目注入的大肆宣传,而且这个技巧几乎无处不在,因为每个人都使用mysqli_real_escape_string。

我必须在这里陈述一个问题:如何逃避cakephp中的变量 - 真的很安全吗?

更新: IRC中的一些人声明,REQUEST字符串必须转义并且不能自行查询。他们可能是正确的,那么我怎么能在GET请求字符串中转义%和_chars而不使用自定义函数..任何sanitize方法都可以做到这一点?

+0

'%'和'_'只是'LIKE'比较中的特殊字符。因此答案很简单:在将'$ str'传递到数据库之前,只需要'str_replace(array('%','_'),array('\\%','\ _'),$ str)''用于“LIKE”比较。如果它是例如插入或与任何其他比较操作员一起使用,无论如何它都不是危险的。这究竟是否会造成问题?我原以为MySQL会将一行中多于一个'%'的任何序列视为一个'%' - 尽管我可能对此错误。 – DaveRandom 2012-07-25 16:16:43

+0

是的,我们只是在顶部有了这个网址的DDOS,这就是为什么它非常重要。我亲自跟踪它 – holms 2012-07-25 16:33:48

+1

是的,但它实际上有什么影响?它影响MySQL还是仅仅是Web服务器进程? DDOS攻击的最终坏结果是什么? – DaveRandom 2012-07-25 16:35:03

回答

1

这并不意味着Cake容易受到SQL注入的影响,因为它在使用预准备语句的下腹部,它确实意味着您在CakePHP中使用LIKE搜索查询,并且它允许使用通配符。

我不认为这是理想的行为,因为我在开发过程中也发现了这一点,我刚才有这一行发现现在使用LIKE

$term = str_replace('%', ' ', $term); 

你不需要逃避到你自己的手中,框架为你处理。

+0

好的瓶颈可能是GET请求字符串,所以我不想使用任何自定义方法,我更新了这个问题 - cakephp的任何方法都会在请求字符串中转义%和_符号? – holms 2012-07-25 16:29:28

0

您显示的代码示例是安全的。此行:

$data = "'" . mysqli_real_escape_string($this->connection, $data) . "'"; 

转义特殊字符。该方法检查变量的类型 - 如果它不是字符串,则不需要转义。

很高兴看到mysql_real_escape_string()所谓的“漏洞”的来源。

+1

只有在执行SET NAMES查询时,才会出现'mysql_real_escape_string()'中的漏洞。在这种情况下,libmysql在执行转义时执行的字符集评估有缺陷,因为连接字符集已更改,但libmysql不知道它,并将继续在转义操作中使用旧字符集。除此之外,它是安全的,并且可以通过使用'mysql_set_charset()'而不是'SET NAMES'来完全缓解这个问题。是的,安全孔非常小,但它仍然是一个洞。 – DaveRandom 2012-07-25 16:14:12

+0

@Juhana这个函数不会跳过%和_,我们最近得到了DDOS,因为这个字符在get param中,我只是在CAKEPHP框架中请求简单的函数,它可以在GET字符串中过滤它们。在我看来,这个字符在默认情况下应该用mysql_real_escape_string()(在cakephp中由sanitazation类使用)逃脱 – holms 2012-07-31 10:09:20

+0

DDOS与消毒无关。如果您使用'LIKE',请手动转义字符。其他地方转义'%'或'_'不起作用。 Cake不能自动将它们转义出来,否则根本就不能使用LIKE'查询。 – JJJ 2012-07-31 12:20:25