pdo防止sql注入

时间:2012-08-04 04:50:18

标签: php sql-injection

我正在尝试将访问者的输入插入数据库 这有效,但是 - 这是否足以阻止sql注入?

<?php
$db_host = "localhost";
$db_name = "db_qadenza";
$db_user = "root";

$odb = new PDO ("mysql:host=" . $db_host . ";dbname=" . $db_name, $db_user);

if(isset($_POST['Submit']))
{
$user = $_POST['user'];
$pass = $_POST['pass'];
$mail = $_POST['mail'];
$confirm_key=md5(uniqid(rand()));

$q = "INSERT INTO members (user, pass, mail, confirm_key)
VALUES(:user, :pass, :mail, :confirm_key);";

$query = $odb->prepare($q);
$results = $query->execute(array(
":user"=>$user,
":pass"=>$pass,
":mail"=>$mail,
":confirm_key"=>$confirm_key,
));

exit();
}
?>

3 个答案:

答案 0 :(得分:4)

您的代码存在两个问题。

  1. 您正在使用模拟的预准备语句。这是PDO_MYSQL驱动程序的默认行为。要绕过它,你应该添加:

    $odb->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    

    与缺少与DB通信的字符集相结合,这可以使您的代码对注入开放。要建立连接,您应该使用:

    $odb = new \PDO('mysql:host=localhost;dbname=******;charset=UTF-8', 
                    'user', 'pass');
    
  2. 您的哈希密码方法不安全(或实际上不存在)。相反,您应该对CRYPT_BLOWFISHcrypt()使用PBKDF2函数,并为每个密码使用不同的盐。

  3. 此外,您可以考虑使用bindParam()方法来设置命名参数的使用,因为通过execute()设置它们会将值绑定为PDO::PARAM_STR,但有other options你可能觉得有用。

答案 1 :(得分:2)

是。只要用户定义的值作为传递的变量输入,prepare($query)方法就可以确保不会发生sql注入。

从链接页面:

  

如果应用程序专门使用预准备语句,开发人员可以确保不会发生SQL注入[...]

答案 2 :(得分:1)

是。它看起来很好。

如果您愿意,还可以创建其他mysql用户,以便在SQL注入时限制范围。您正在以root身份连接。

另请考虑使用密码散列方案,例如salt + BCrypt。