我知道sql注入已经在stackoverflow上讨论了很多次。
使用此方法有什么缺点
foreach($_POST as &$value)
$value = mysql_real_escape_string($value);
它只有两行,看起来使用起来非常方便,但我认为这不是一个非常常用的方法。
请不要将讨论转变为准备好的陈述和PDO,即使它可能被认为是最佳实践。
答案 0 :(得分:6)
使用此代码的主要缺点是您正在修改POST数组中的数据。这可能会影响稍后对POST数组的操作(如输出到屏幕)。如果您正在与其他程序员合作,他们可以合理地期望POST阵列保持不变,这也可能导致混淆。由于上一个原因,它还可能使代码维护更加困难。任何处理代码的人都需要知道你修改了POST数组。
我的建议是,如果你开始使用mysql_real_escape_string而不是参数化查询,那就是确保你将它与sprintf和正确的类型说明符结合使用,如下所示:
$query = sprintf("INSERT INTO purchases (amount, num_items, prod_descrip)
VALUES (%f, %d, '%s')",
mysql_real_escape_string($_POST['amount'])
mysql_real_escape_string($_POST['num_items'])
mysql_real_escape_string($_POST['prod_descrip']));
请注意,%f适用于float,%d适用于整数,%s适用于字符串值。另请注意,我在查询字符串中直接使用$ _POST数据而没有任何类型的验证,我在实践中不会这样做(仅为了简单起见)。
答案 1 :(得分:4)
任何数据都不应该在收集时被转义,但在使用它时,因为您可能在不同的上下文中使用相同的数据(MySQL查询,preg模式,HTML输出),并且每个上下文都需要不同的转义。此外,如果您以这种方式转义数据,那么您正在使用其他数据源做什么,假设您正在从文件或远程XML服务中读取值?很容易忘记逃避它,并且很容易忘记哪些值被转义而哪些没有,要么让您的应用程序易受攻击,要么以双重转义结束。正如@genesisφ所指出的,上述方法也应该是递归的,以处理数组。并且您需要在查询中的每个值周围使用引号,包括数字,否则您很容易受到这些参数中的SQL注入攻击。
答案 2 :(得分:3)
如果您希望为MySQL查询正确格式化每个POST变量,则此方法才有意义。
这与Magic Quotes背后的理论基本相同,后者因为有充分理由而被弃用。
答案 3 :(得分:2)
我不会用这个。有些情况下你只需要intval或你传递POST数组,这将在这里出错。您可以使用自己的函数
简化每次编写mysql_real_escape_string()的过程function mres($what){
return mysql_real_escape_string($what);
}
并使用它
$query = '
select column
from table
where column2 = "'.mres($_POST['var']).'"';
答案 4 :(得分:1)
在处理POST / GET数据之前逃避POST / GET数据并不是一个好习惯。通常,在创建查询时应该转义数据。例如:
$query = '
select column_name
from table_name
where column_name = "'. mysql_real_escape_string($_POST['var_name']) .'"
';
答案 5 :(得分:0)
为了提高效率,我建议这样的事情
$dbArr = array( 'key1','key2',...); //make these keys correspond with the POST vars you want in the db
foreach($dbArr as $goodCol){
$sanitized[$goodCol] = mysql_real_escape_string($_POST[$goodCol]);
}
答案 6 :(得分:0)
如果您喜欢正则表达式并想要明确控制输入,请试试这个。
function match_implode($filter,$val,$cut=255){
$m=array();
if(!is_string($val)){
return false;
}
preg_match_all($filter,$val,$m);
if(!empty($m[0])){
return substr(implode($m[0]),0,$cut);
}
return false;
}
//Only Alpha-numeric with a max-length of 20 chars.
echo match_implode("{[A-Za-z0-9]}",$_POST["alpha"],20);
//Practical use
if($user_id=match_implode("{[0-9]}",$_POST["id"])){
mysql_query("UPDATE user SET last_login=UNIX_TIMESTAMP() WHERE user_id=$user_id");
}
//If you need to parse and escape email :)
if($email=match_implode("{^[a-z0-9\å\ä\ö._-]+@[a-z0-9\å\ä\ö.-]+\.[a-z]{2,6}$}i",$_POST["email"])){
mysql_query("UPDATE user SET last_login=UNIX_TIMESTAMP() WHERE email='$email'");
}