使用password_verify()的SQL注入

时间:2018-06-08 08:08:24

标签: php sql mysqli

我正在创建一个网站,我希望防止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()函数?

由于

2 个答案:

答案 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()或参数绑定修复了这两个问题,您仍应确保您的用户名是唯一的,并且每次验证尝试只测试一行最大值。