我正在创建一个网站,我希望防止SQL注入发生。我有代码接收POST数据,做一个MYSQL查询来检查它。然后运行mysqli_num_rows()函数,然后执行password_verify()。
这是我的代码:
<?php
$Username = $_POST['Username'];
$Password = $_POST['Password'];
$Connect = mysqli_connect('localhost', 'user', 'pass', 'DB');
$sql = "SELECT * FROM table WHERE Username = '$Username'";
$output = mysqli_query($Connect, $sql);
if (mysqli_num_rows($output) > 0) {
while($row = mysqli_fetch_assoc($output)) {
if (password_verify($Password, $row['Password'])) {
$_SESSION = $row;
header('Location: Account.php');
} else {
echo 'Invalid Username or Password';
}
}
} else {
echo 'Invalid Username or Password';
}
?>
我想知道是否有任何方法可以通过SQL注入绕过password_verify()函数?
由于
答案 0 :(得分:0)
我想知道是否有办法通过SQL注入绕过
password_verify()
函数?
是的,经过时尚。可以使用以下行的输入将精心设计的数据注入查询结果:
$Username = "' UNION SELECT 1, 'username', 'fake password hash', …, '";
导致查询
SELECT * FROM table WHERE username = ''
UNION SELECT 1, 'username', 'fake password hash', …, ''
这可用于注入一个包含结果的假行,其密码哈希的密码为攻击者所知。
password_verify()
不会保护您免受SQL注入。使用准备好的陈述。
答案 1 :(得分:0)
您的代码有点怀疑。为什么要允许重复的用户名?这似乎是一个评论,但它对你提出的问题非常重要。您向我们展示的代码很容易被注射。如果您知道它可以被利用,那么只有解决问题才是正确的方法。
除了通过提交anything' OR 'A'='A
强制检查存储在数据库中的每个密码的暴力之外,攻击者还可以在UNION中发送用户名和选择的散列密码 - 请考虑:
SELECT * FROM table
WHERE Username = 'xxx'
UNION SELECT 'root' AS username,
'$6$ErsDojKr$7wXeObXJSXeSRzCWFi0ANfqTPndUGlEp0y1NkhzVl5lWaLibhkEucBklU6j43/JeUPEtLlpRFsFcSOqtEfqRe0'
AS Password'
在正确转义数据的同时,使用mysqli_real_escape_string()或参数绑定修复了这两个问题,您仍应确保您的用户名是唯一的,并且每次验证尝试只测试一行最大值。