Безопасная система входа и регистрации с хешированными паролями - PullRequest
1 голос
/ 13 июля 2020

Итак, у меня есть таблица, в которой я храню информацию о пользователях, такую ​​как хешированные пароли, электронные письма, имена и т. Д. c. И я сталкиваюсь с этой проблемой. Когда два пользователя имеют одинаковый пароль, один из них может получить доступ к другому аккаунту, зная его адрес электронной почты. Какие решения вы могли бы предложить? Спасибо.

Вот как я пробую:

<?php
$pscoo = $_COOKIE['sw12Hj0i6y'];
$dthshcoo = $_COOKIE['dthsh'];

$pass = $_POST['pass']; // i get this from other page
$mail = $_POST['mail']; // i get this from other page

include 'admin/conn.php';

$get = "SELECT * FROM `users` WHERE `mail` = '$mail'";
$res = mysqli_query($conn, $get);

if (!isset($pscoo) && !isset($dthsh)) {
  while ($row = mysqli_fetch_assoc($res)) {
    $slt = $row['salt'];
    $hsh = $row['hash'];
    $cnct = $slt.$pass;
    if (password_verify($cnct, $hsh)) {
      // do smth
    }
    else {
      // reject
    }
  }
}
?>

1 Ответ

1 голос
/ 13 июля 2020

Прежде всего, я бы посоветовал выполнить следующие требования OW ASP Стандарт проверки безопасности приложений (ASVS):

2.1.1 Убедитесь, что пользователь установил пароли имеют длину не менее 12 символов.

2.1.2 Убедитесь, что разрешены пароли длиной 64 символа

2.1.3 Убедитесь, что пароли могут содержать пробелы и не выполняется усечение

2.1.4 Убедитесь, что в паролях разрешены символы Юникода. Одна кодовая точка Unicode считается символом, поэтому 12 символов эмодзи или 64 символа кандзи должны быть действительными и разрешенными.

2.1.7 Убедитесь, что пароли, отправленные во время регистрации учетной записи, входа в систему и смены пароля, сравниваются с набором взломанных паролей либо локально (например, 1000 или 10000 наиболее распространенных паролей, которые соответствуют политике паролей системы), либо с использованием внешнего API. При использовании API необходимо использовать доказательство с нулевым разглашением или другой механизм, чтобы гарантировать, что пароль в виде обычного текста не будет отправлен или использован для проверки статуса нарушения пароля. Если пароль взломан, приложение должно потребовать, чтобы пользователь установил новый пароль, не взломанный.

2.1.8 Убедитесь, что имеется измеритель надежности пароля, чтобы помочь пользователям установить более надежный пароль.

2.1 .9 Убедитесь, что нет правил составления паролей, ограничивающих допустимые типы символов. Не должно быть требований к прописным или строчным буквам, цифрам или специальным символам.

ПРИМЕЧАНИЕ: ASVS обобщает передовой опыт, определенный исследователями безопасности, крупными игроками в области безопасности (NIST), а также общие передовые практики. Требования, описанные в главе 2.1, являются требованиями Уровня 1, что означает, что фактически все вновь построенные системы должны им соответствовать.

После выполнения того, что требуется выше, вероятность коллизий минимальна (незначительна), но всегда будет и НЕ следует предотвращать. (Иногда, предотвращая дублирование паролей, люди создают механизм для перечисления пользователей и паролей, что плохо.)

Теперь по поводу вашего кода. Это место заставляет меня задуматься:

$slt = $row['salt'];
$hsh = $row['hash'];
$cnct = $slt.$pass;

Обычно функция деривации ключа, такая как bcrypt, scrypt, PBKDF2, не нуждается в добавлении соли к паролю вручную. Это означало бы, что вы используете не KDF, а какую-то хеш-функцию (которая неоптимальна с точки зрения безопасности) ... Субоптимальная - это неправильно.

Кстати, это SQL инъекционная уязвимость: $get = "SELECT * FROM 'users' WHERE mail = '$mail'"; в вашем логе аутентификации c? Итак, , пожалуйста, исправьте это как можно скорее и обновите свой вопрос на StackOverflow.

...