我在PHP表单处理程序中有以下代码块:
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注入攻击的简单目标?
答案 0 :(得分:4)
对于sql注入,我将使用prepared statement切换到PDO。
您可以在值上使用简单的is_array()
来检查数组,然后循环遍历它。你是正确的,因为你的filter
函数不能正确处理数组。
编辑:如果您使用PDO和准备好的声明,则不再需要mysql_real_escape_string
。您也不需要strip_tags
,htmlentities
和trim
来安全地将信息存储在数据库中,当您向浏览器输出信息时,它们是必需的(trim
当然不是。htmlspecialchars
。 ..),虽然{{1}}就足够了。最好为当时输出的介质准备正确的信息/输出。
答案 1 :(得分: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()
。如果您需要它,那么在输出值时使用它 - 而不是在将它们作为输入时使用它。
答案 2 :(得分:2)
array_walk_recursive($array,function(&$item){
$item=mysql_real_escape_string($item);
});
答案 3 :(得分: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 */
答案 4 :(得分:1)
不要手动清理输入,而是使用预留 准备好的语句和占位符。这将透明地将输入传递给数据库,使其不需要进行转义,因此不易受SQL注入攻击。这是目前最好的做法。
有关详细信息,请参阅以下内容:http://php.net/manual/en/pdo.prepared-statements.php
答案 5 :(得分: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;
}
答案 6 :(得分: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。你会喜欢的。