2011-08-01 54 views
3

之前,我已经在PHP形式处理程序下面的代码块:消毒数组值的MySQL插入

function filter($data) { 
    $data = trim(htmlentities(strip_tags($data))); 

    if (get_magic_quotes_gpc()) { 
     $data = stripslashes($data); 
    } 
    $data = mysql_real_escape_string($data); 

    return $data; 
} 

foreach($_POST as $key => $value) { 
    $data[$key] = filter($value); 
} 

我修改我形式现在包括复选框组:

例如:

<input type="checkbox" name="phone_prefs[]" value="prefer_home"> 
<input type="checkbox" name="phone_prefs[]" value="prefer_cell"> 
<input type="checkbox" name="phone_prefs[]" value="prefer_work"> 
etc. 

由于这段代码,我现在在我的_POST变量中有数组,而不仅仅是字符串。

我正确地认为我的filter()函数不会真正清理数组吗?我需要对filter()函数进行哪些更改以确保复选框的数组完全消毒,而不是SQL注入攻击的轻松目标?

+1

您不需要结合** htmlentities **和** strip_tags **。 – Karolis

+1

你也不需要使用htmlentities来过滤输入。使用htmlentities为HTML输出转义内容。 –

回答

2

你的功能是相当不错的,但如果你把它递归的,它会抓取嵌套数组,你

function filter(&$array) { 
    $clean = array(); 
    foreach($array as $key => &$value) { 
     if(is_array($value)) { 
      filter($value); 
     } else { 
      $value = trim(strip_tags($value)); 
      if (get_magic_quotes_gpc()) { 
       $data = stripslashes($value); 
      } 
      $data = mysql_real_escape_string($value); 
     } 
    } 
} 

filter($_POST); # filters $_POST and any nested arrays by reference 

编辑:离开了htmlentities()。如果您需要它,请在输出值时使用它 - 不要在输入值时使用它。

4

至于sql注入,我会切换到PDO使用prepared statement

你可以在你的值上使用简单的is_array()来检查一个数组,然后遍历它。你是正确的,因为你的filter函数不能正确处理数组。

编辑:如果您使用PDO和准备好的语句,则不再需要mysql_real_escape_stringstrip_tags,htmlentitiestrim也不需要将信息安全地存储在数据库中,当您向浏览器输出信息时(trim当然不是......)需要它们,但htmlspecialchars就足够了。准备好你的信息/输出,正确地输出你正在输出的媒体总是最好的。

+0

你为什么要切换到PDO? –

+0

@Eric J.我已经添加了,忘了提及准备好的语句...... – jeroen

+0

可能值得指出的是,使用预准备语句,不再需要转义。 – Mike

1

您正在使用$ _POST的foreach,它只循环一次,使用Array并像字符串一样处理它。

尝试使用:

foreach($_POST['phone_prefs'] as $key => $value) 

编辑:

我相信我误解你的问题:

foreach($_POST as $key => $value) 
    if (is_array($value)) 
     foreach($_POST[$key] as $key2 => $value2) 
      /* Setting stuff */ 
    else /* Setting same stuff */ 
1

除了手动消毒的投入,使用总是预处理语句占位符。这将透明地将输入传递给数据库,使得它不需要转义,因此不容易受到SQL注入的影响。这是目前最好的做法。

更多信息请参阅以下内容:http://php.net/manual/en/pdo.prepared-statements.php

2
array_walk_recursive($array,function(&$item){ 
    $item=mysql_real_escape_string($item); 
}); 
1

我使用各种网站上我已经创建了:

public function clean($dirty) { 
    if (!is_array($dirty)) { 
     $dirty = ereg_replace("[\'\")(;|`,<>]", "", $dirty); 
     $dirty = mysql_real_escape_string(trim($dirty)); 
     $clean = stripslashes($dirty); 
     return $clean; 
    } 
    $clean  = array(); 
    foreach ($dirty as $p => $data) { 
     $data = ereg_replace("[\'\")(;|`,<>]", "", $data); 
     $data = mysql_real_escape_string(trim($data)); 
     $data = stripslashes($data); 
     $clean[$p] = $data; 
    } 
    return $clean; 
} 
0

使用mysql_real_escape_string意味着使用的功能,这是不是最好的便利之前,MySQL连接是必需的。我曾经在这种情况下使用工作:

function real_escape_string($aQuery) { 
    if (!is_string($aQuery)) { 
     return FALSE; 
    } else { 
     return strtr($aQuery, array("\x00" => '\x00', "\n" => '\n', "\r" => '\r', '\\' => '\\\\', "'" => "\'", '"' => '\"', "\x1a" => '\x1a')); 
    } 
} 

但绝对,最好是使用PDO准备语句,而不是mysql。你会喜欢它。