我正在尝试将访问者的输入插入数据库 这有效,但是 - 这是否足以阻止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();
}
?>
答案 0 :(得分:4)
您的代码存在两个问题。
您正在使用模拟的预准备语句。这是PDO_MYSQL驱动程序的默认行为。要绕过它,你应该添加:
$odb->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
与缺少与DB通信的字符集相结合,这可以使您的代码对注入开放。要建立连接,您应该使用:
$odb = new \PDO('mysql:host=localhost;dbname=******;charset=UTF-8',
'user', 'pass');
您的哈希密码方法不安全(或实际上不存在)。相反,您应该对CRYPT_BLOWFISH
或crypt()
使用PBKDF2函数,并为每个密码使用不同的盐。
此外,您可以考虑使用bindParam()
方法来设置命名参数的使用,因为通过execute()
设置它们会将值绑定为PDO::PARAM_STR
,但有other options你可能觉得有用。
答案 1 :(得分:2)
答案 2 :(得分:1)
是。它看起来很好。
如果您愿意,还可以创建其他mysql用户,以便在SQL注入时限制范围。您正在以root
身份连接。
另请考虑使用密码散列方案,例如salt + BCrypt。