Проблемы с подготовленными утверждениями для запроса на выборку - PullRequest
0 голосов
/ 11 мая 2018

У меня есть приложение, работающее на php / mysql, и оно недавно вступило в производственную стадию, поэтому мне нужно защитить всю инфраструктуру, начиная с некоторой защиты от внедрения SQL. Одна из вещей, которые я делаю, - это преобразование всего ввода от пользователей в подготовленное утверждение вместо прямого запроса. Это работало отлично, пока я не начал работать на странице входа. Следующий код (только запрос MySQL)

  1. (НЕОБХОДИМО), но функционирующий код, который я использую сегодня
  2. КОД, чтобы заменить его, который не работает.

В этом примере 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);

Второй фрагмент кода не работает, так как результат запроса в любом случае будет нулевым, с правильной или неправильной комбинацией usr / pass.

Если этого недостаточно, я могу опубликовать целые фрагменты, но я думаю, что эта проблема как-то связана с запросом SQL. Спасибо за вашу помощь

1 Ответ

0 голосов
/ 12 мая 2018

Вот как я могу его кодировать:

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, или что-то еще происходит, вы хотите знать.

...