Я вижу, что вы храните хэш пароля в базе данных, но для удобства других читателей, никогда не хранит пароли в виде простого текста в базе данных. Вы не хотите быть , как Monster.com.uk !
Вы должны использовать более сильную функцию хеширования, чем MD5()
. В идеале вы должны использовать SHA256. Этот хеш-метод доступен в PHP с использованием функции hash()
.
Вы также должны применить случайную соль к паролю. Сохраните различные значения соли для учетной записи каждого пользователя. Это помогает отразить атаки по словарю и радужный стол атаки.
Вы должны научиться использовать расширение mysqli вместо старого расширения mysql. Mysqli поддерживает параметризованные запросы, поэтому вы можете уменьшить уязвимость к некоторым атакам с использованием SQL-инъекций.
Вот пример кода. Я не проверял это, но это должно быть довольно близко к работе:
$input_login = $_POST['login'];
$input_password = $_POST['password'];
$stmt = $mysqli->prepare("SELECT password, salt FROM customer WHERE login = ?");
$stmt->bind_param("s", $input_login);
$stmt->execute();
$stmt->bind_result($password_hash, $salt);
while ($stmt->fetch()) {
$input_password_hash = hash('sha256', $input_password . $salt);
if ($input_password_hash == $password_hash) {
return true;
}
// You may want to log failed password attempts here,
// for security auditing or to lock an account with
// too many attempts within a short time.
}
$stmt->close();
// No rows matched $input_login, or else password did not match
return false;
Некоторые другие люди предполагают, что запрос должен проверить на login = ? AND password = ?
, но я не люблю это делать. Если вы сделаете это, вы не сможете узнать, произошел ли сбой при поиске, потому что логин не существовал или пользователь ввел неправильный пароль.
Конечно, вы не должны сообщать пользователю, что вызвало неудачную попытку входа в систему, но вам может потребоваться знать, чтобы вы могли регистрировать подозрительные действия.
@ Хавьер говорит в своем ответе, что вы не должны извлекать пароль (или хэш пароля в этом случае) из базы данных. Я не согласна
Хавьер показывает вызов md5()
в коде PHP и отправку полученной хеш-строки в базу данных. Но это не поддерживает соление пароля легко. Вы должны сделать отдельный запрос, чтобы получить соль этого пользователя, прежде чем вы сможете сделать хеш в PHP.
Альтернативой является отправка пароля в виде открытого текста по сети из приложения PHP на сервер базы данных. Любой, кто прослушивает вашу сеть, может увидеть этот пароль. Если вы регистрируете SQL-запросы, пароль может увидеть любой, кто получит доступ к журналам. Мотивированные хакеры могут даже погрузиться в мусорную корзину, чтобы найти старые носители с резервной копией файловой системы, и могут читать файлы журналов таким образом!
Меньший риск - извлечь строку хэша пароля из базы данных в приложение PHP, сравнить ее с хэшем ввода пользователя (также в коде PHP), а затем отбросить эти переменные.