为选择查询准备语句的问题

时间:2018-05-11 13:26:02

标签: php mysql prepared-statement mariadb sql-injection

我有一个在php / mysql上运行的应用程序,它最近进入了生产阶段,因此我需要保护整个基础架构,从一些防止SQL注入开始。 我正在做的一件事是将用户的所有输入转换为预备语句而不是直接查询。 这非常有效,直到我开始在登录页面上工作。 以下代码是(仅限mysql查询)

  1. (UNSECURE)但功能正常的代码我今天使用
  2. 代替它的CODE不起作用。
  3. 对于这个例子,user_list将是我在数据库和usr上的表,pswHash 用于检查登录的字段。 id将是自动递增的行标识符。

    1)

    $sql_query = "SELECT * FROM user_list WHERE usr = $user AND pswHash = $passHash";
    

    2)

    $stmt = $mysqli->prepare("SELECT * FROM user_list WHERE usr=? AND pswHash=?");
    $stmt->bind_param('ss', $user, $passHash);
    

    第二个代码片段不起作用,因为查询的输出在任何情况下都是null,无论是正确还是错误的usr / pass组合。

    如果这还不够,我可以发布整个片段,但我想这个问题与SQL查询有关。 谢谢你的帮助

1 个答案:

答案 0 :(得分:0)

以下是我编码的方法:

function password_matches($mysqli, $user, $pass) {
    $stmt = $mysqli->prepare("SELECT pswHash FROM user_list WHERE usr=?");
    // always check for errors after prepare()
    if (!$stmt) {
      error_log($mysqli->error);
      return false;
    }
    $stmt->bind_param('s', $user);

    $ok = $stmt->execute();
    // always check for errors after execute()
    if (!$ok) {
      error_log($mysqli->error);
      return false;
    }

    $result = $stmt->get_result();
    while ($row = $result->fetch_assoc()) {
      if (password_verify($pass, $row['pswHash'])) {
        return true;
      }
    }
    // if the result set had zero matches for $user,
    // or if there were any matches for $user, but none of them
    // had a password hash matching the input
    return false;
}

这是假设您在将密码哈希插入数据库之前使用password_hash()创建密码哈希。

始终同时检查prepare()execute(),看看它是否返回 false 。如果是,请记录$mysqli->error,并继续观察您的http服务器错误日志。这是开发SQL查询时的一般建议。如果您编写了错误的SQL语法,或者您没有正确的SQL权限,或者其他事情发生,那么您想知道。