基本上,我希望我的代码可以安全地从SQL注入。我在网上读到mysqli_real_escape_string
对SQL注入是不安全的,并且读取参数化是要走的路。因此,从下面的代码中,我可以将帐户添加到数据库中,但我无法检查该帐户是否已存在。
<?php
require 'privstuff/dbinfo.php';
$firstname = $_POST["firstname"];
$password1 = $_POST["password1"];
$email = $_POST["email"];
$ip = $_SERVER['REMOTE_ADDR'];
$username = $_POST["username"];
$mysqli = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_DATABASE);
if(mysqli_connect_errno()) {
echo "Connection Failed. Please send an email to owner@othertxt.com regarding this problem.";
exit();
}
//$username = mysqli_real_escape_string($mysqli,$_POST['username']);
//$result = mysqli_query($mysqli,"SELECT `username` FROM `accounts` WHERE username = '$username'");
if ($stmt = $mysqli->prepare("SELECT `username` FROM `accounts` WHERE username = ?")) {
$stmt -> bind_param("s", $username);
$stmt -> execute();
$stmt -> bind_result($result);
$stmt -> fetch();
$stmt -> close();
}
if(mysqli_num_rows($result)>0){
header('Location: /register.html');
}else{
if ($stmt = $mysqli->prepare("INSERT INTO `accounts`(`firstname`, `username`, `password`, `email`, `ip`) VALUES (?,?,?,?,?)")) {
$stmt -> bind_param("sssss", $firstname, $username, password_hash($password1, PASSWORD_BCRYPT), $email, $ip);
$stmt -> execute();
$stmt -> bind_result($result);
$stmt -> fetch();
$stmt -> close();
}
$mysqli->close();
header('Location: /login.html');
}
?>
由于问题已暂停,我无法添加自己的答案。 Reddit上有人给出了这个问题的精彩解释。 Here it is
答案 0 :(得分:1)
参数化的一个好处是,您不再需要直接关注各种数据类型的handling of quotes - 这些将由bind处理:
$mysqli->prepare("SELECT `username` FROM `accounts` WHERE username = ?" ...
答案 1 :(得分:1)
除了@Stuart的上述答案(涵盖预备语句中的引号)之外,您在错误的地方引用了num_rows
:
$stmt -> bind_result($result);
if(mysqli_num_rows($result)>0){
您应该将它引用到语句对象:
if($stmt->num_rows > 0) {
// do whats necessary
}
在插入后获取行没有意义,你实际上并不需要那些。
以下是它的汇编:
<?php
require 'privstuff/dbinfo.php';
$firstname = $_POST["firstname"];
$password1 = $_POST["password1"];
$email = $_POST["email"];
$ip = $_SERVER['REMOTE_ADDR'];
$username = $_POST["username"];
$mysqli = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_DATABASE);
if(mysqli_connect_errno()) {
echo "Connection Failed. Please send an email to owner@othertxt.com regarding this problem.";
exit;
}
if ($stmt = $mysqli->prepare("SELECT `username` FROM `accounts` WHERE username = ?")) {
$stmt->bind_param("s", $username);
$stmt->execute();
}
if($stmt->num_rows > 0) {
header('Location: /register.html');
} else {
if ($stmt = $mysqli->prepare("INSERT INTO `accounts`(`firstname`, `username`, `password`, `email`, `ip`) VALUES (?,?,?,?,?)")) {
$stmt->bind_param("sssss", $firstname, $username, password_hash($password1, PASSWORD_BCRYPT), $email, $ip);
if($stmt->execute()) {
header('Location: /login.html');
$stmt->close();
} else {
die($mysqli->error);
}
}
}