如果我使用MySQLi预处理语句,是否需要转义变量?

时间:2014-07-12 19:30:43

标签: php mysql mysqli prepared-statement

如果我使用MySQLi准备好的语句如下:

$stmt = $con1->prepare("UPDATE Login SET Session='LoggedOut' where Session=?");
$stmt->bind_param('s',$Session);
$stmt->execute();
$stmt->close();

我仍然需要像$Session一样使用mysqli_real_escape_string();来转义我的变量,如下所示:

$Session = mysqli_real_escape_string($con1, $_COOKIE['Session']);
$stmt = $con1->prepare("UPDATE Login SET Session='LoggedOut' where Session=?");
$stmt->bind_param('s',$Session);
$stmt->execute();
$stmt->close();

2 个答案:

答案 0 :(得分:6)

不,如果您在应用程序中的任何地方使用预准备语句,则可以安全地进行SQL注入。然而,一个重要的"陷阱"是二阶段注入攻击,当某些查询使用准备好的语句而其他查询使用时不会发生。

根据关于SO的类似问题的this回答:

  

准备好的语句/参数化查询足以阻止该语句上的第一顺序注入。如果在应用程序中的任何其他位置使用未经检查的动态sql,则仍然容易受到二阶注入的影响。

总之,预准备语句在发送的数据和SQL查询本身之间创建了一个分隔,确保数据不会被误解为SQL查询。但是,攻击者仍然可以将SQL作为数据输入,虽然在使用预准备语句时首次存储它时不会执行,但在检索所述结果时仍必须谨慎。准备好的语句可以保护您在该特定位置的应用程序,但由于SQL仍然允许存储在数据库中,因此如果您以后在没有参数化的情况下使用该数据,则您的应用程序是不安全的。

答案 1 :(得分:3)

不,你没有。

这是您需要的唯一答案。

另一个答案中所有混乱的谈话都是无关紧要的。这家伙正试图告诉你,如果你愚蠢到不能在整个地方使用准备好的陈述,那么你就处于危险之中。这是非常明显的,与准备好的陈述本身无关。