代码之家  ›  专栏  ›  技术社区  ›  Nick Evans

带密码的SQL注入

  •  0
  • Nick Evans  · 技术社区  · 6 年前

    我正在做一个网站,我想防止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 回复  |  直到 6 年前
        1
  •  0
  •   gone    6 年前

    我想知道有没有办法绕过 password_verify() 使用SQL注入的函数?

    是的,时尚之后。可以使用沿以下行的输入将精心编制的数据插入查询结果:

    $Username = "' UNION SELECT 1, 'username', 'fake password hash', …, '";
    

    导致查询

    SELECT * FROM table WHERE username = ''
    UNION SELECT 1, 'username', 'fake password hash', …, ''
    

    这可用于插入包含密码哈希的结果的伪行,攻击者知道该哈希的密码。

    密码验证() 不保护您不受SQL注入的影响。使用准备好的陈述。

        2
  •  0
  •   symcbean    6 年前

    你的代码有点可疑。为什么允许重复用户名?这看起来像是一个评论,但它对你提出的问题相当重要。你给我们展示的代码容易被注入。只有在你知道这个问题可以被利用的情况下才能解决它,这不是正确的方法。

    除了通过提交强制检查数据库中存储的每个密码之外 anything' OR 'A'='A 攻击者可以在联合中发送用户名和所选哈希密码-请考虑:

     SELECT * FROM table 
     WHERE Username = 'xxx'
     UNION SELECT 'root' AS username, 
     '$6$ErsDojKr$7wXeObXJSXeSRzCWFi0ANfqTPndUGlEp0y1NkhzVl5lWaLibhkEucBklU6j43/JeUPEtLlpRFsFcSOqtEfqRe0' 
     AS Password'
    

    在正确转义数据时,使用mysqli_real_escape_string()或参数绑定都可以解决这两个问题,但仍应确保用户名是唯一的,并且每次身份验证尝试只测试一行最大值。