带有 MySQL 连接的 PHP 中的参数化查询

Már*_*égh 8 php mysql sql-injection login-page

我读过关于 SQL 注入的内容,所以我在我的网站上进行了尝试,当然它奏效了。我们正在连接到数据库。所以这是我登录页面的 PHP 代码的一部分:

$userName = $_POST["username"];
$userPass = $_POST["password"];

$query = "SELECT * FROM users WHERE username = '$userName' AND password = '$userPass'";

$result = mysqli_query($dbc, $query); //$dbc is for MySQL connection: $dbc = @mysqli_connect($dbhost, $dbuser, $dbpass, $db)

$row = mysqli_fetch_array($result);

if(!$row){
    echo "No existing user or wrong password.";
}
Run Code Online (Sandbox Code Playgroud)

我一直在寻找解决方案很长时间,但我无法弄清楚如何以参数化的方式使其工作。你能帮我完成我的代码以防止 SQL 注入吗?

Fab*_*bio 10

干得好

$stmt = mysqli_prepare($dbc, "SELECT * FROM users WHERE username = ? AND password = ?");
mysqli_stmt_bind_param($stmt, "s", $userName);
mysqli_stmt_bind_param($stmt, "s", $userPass);
mysqli_stmt_execute($stmt);
$row = mysqli_stmt_fetch($stmt);
Run Code Online (Sandbox Code Playgroud)

Documentation

作为旁注,我建议加密您的密码或更好地使用哈希以确保安全,将密码存储为纯文本是不好的

  • @MárkVégh,当然它仍然接受它 - 它在输入中。但是,它无法执行!这就是准备好的语句的重点。占位符中的数据仅被视为文本。 (2认同)
  • @MárkVégh,不,提供的用户名和密码必须与数据库中的记录匹配。将会发生的情况是,查询不会返回任何内容,因为提供的用户名和密码与任何记录都不匹配。请记住,它们只是文本字符串,没有任何其他含义。关键是匹配记录的唯一方法是提供正确的用户名和密码。无法使用作为输入文本提供的任何内容来修改查询。 (2认同)
  • @MárkVégh,准备好的查询_不是文本替换_。会发生什么: 1) `prepare` 步骤完全解析了 sql。以后无法更改。占位符标记稍后将给出保存文本值的变量的位置。2) `bind` 告诉数据库去哪里寻找值。3) `Execute` 使用变量中的值运行查询。 (2认同)