如果我使用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();
$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();
不,如果您在应用程序中的任何地方都使用准备好的语句,那么可以避免SQL注入。但是,一个重要的“陷阱”是二阶注入攻击,当某些查询使用准备好的语句而其他不使用准备好的语句时,就会发生这种攻击。
根据这个答案在SO类似的问题:
准备好的语句/参数化查询足以防止对该语句进行一阶注入。如果在应用程序的其他任何地方使用未经检查的动态sql,则仍然容易受到二阶注入的攻击。
总而言之,准备好的语句在发送的数据和SQL查询本身之间建立了分隔,确保不会将数据误解为SQL查询。但是,攻击者仍然可以将SQL作为数据输入,尽管如果使用的是准备好的语句,则在首次存储SQL时将不会执行该SQL,但在检索该结果时仍必须谨慎。准备好的语句在那个特定的位置保护您的应用程序,但是由于仍然允许将SQL存储在数据库中,因此如果您稍后在不带参数化的情况下使用该数据,则您的应用程序是不安全的。