问题
I'm trying to insert the visitor's inputs into a database.
This works, but - is this good enough to prevent sql injection ?
<?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();
}
?>
回答1:
There are two issues with your code.
You are using emulated prepared statements. This is the default behavior for PDO_MYSQL driver. To circumvent it, you should add:
$odb->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);In combination with missing charset for the communication with DB, which can make your code open to injections. For establishing the connection you should use:
$odb = new \PDO('mysql:host=localhost;dbname=******;charset=UTF-8', 'user', 'pass');Your method of hashing password is insecure (or, actually, does not exist). Instead you should use crypt() function with
CRYPT_BLOWFISHor PBKDF2 and different salt for each password.
Also , you might consider using bindParam() method for seting the aluse of named parameters, since setting them through execute() would bind the values as PDO::PARAM_STR, but there are other options, that you might find useful.
回答2:
Yes. the prepare($query) method ensures that no sql injection can take place, as long as user defined values are entered as passed variables, which they are for you.
From the linked page:
If an application exclusively uses prepared statements, the developer can be sure that no SQL injection will occur [...]
回答3:
Yes. It looks fine to me.
If you wanted to you can also create additional mysql users to limit the scope in the event of an SQL injection. At the moment you are connecting as root.
Also look into using a password hashing scheme such as, salt + BCrypt.
来源:https://stackoverflow.com/questions/11805986/pdo-to-prevent-sql-injection