2012-07-25 114 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