Password_verify возвращает истину

Я хочу сравнить свой пароль и свой хеш-пароль с password_verify(), но всегда возвращает true. Почему это происходит?

Вот код:

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // username and password sent from form 

    $myusername = mysqli_real_escape_string($db,$_POST['username']);
    $mypassword = mysqli_real_escape_string($db,$_POST['password']); 
    $hash = password_hash($mypassword, PASSWORD_DEFAULT);

    $ourdb = "SELECT handle FROM qa_users WHERE handle = '$myusername' and passhash = '$mypassword'";
    $ourresult = mysqli_query($db,$ourdb);
    $ourrow = mysqli_fetch_array($ourresult,MYSQLI_ASSOC);
    $ouractive = $ourrow['active'];
    $ourcount = mysqli_num_rows($ourresult);

    if (password_verify($mypassword, $hash)){
        echo "hashed";
    }

вы открыты для SQL-инъекций и должны немедленно решить

treyBake 10.07.2019 15:42

Почему нет должен возвращать true? Плюс: обязательное предупреждение «использовать подготовленные операторы».

Marvin 10.07.2019 15:42

откуда вы знаете/ожидаете, что это ложь?

treyBake 10.07.2019 15:42

Вы должны выбрать пароль из базы данных и сравнить его с введенным - вы сравниваете его с самим собой (эффективно).

Nigel Ren 10.07.2019 15:45

Вы не должны использовать mysqli_real_escape_string в именах пользователей или паролях, потому что это может изменить их значение, в результате чего ваш пользователь не сможет войти в систему.

GrumpyCrouton 10.07.2019 15:45

@GrumpyCrouton давно не виделись. Ваше утверждение справедливо только для пароля и только при правильном использовании хеширования. Принимая во внимание, что для присутствующего (недействительного) кода использование допустимо.

Your Common Sense 10.07.2019 15:51

@YourCommonSense Верно, хотя обычно mysqli_real_escape_string вообще не требуется для любого значения при использовании подготовленных операторов. Клянусь, я видел случаи, когда mysqli_real_escape_string меняли чье-то имя пользователя, и они не могли войти на свой сайт. Кроме того, хеширование в коде OP кажется совершенно правильным, если они проверяют неправильно (конечно, их использование в настоящее время недействительно, на самом деле оно ничего не проверяет, оно фактически имеет 0 безопасности от простого входа в систему с любым паролем).

GrumpyCrouton 10.07.2019 16:10

@GrumpyCrouton это может быть только в том случае, когда использование mres() совершенно неправильно, например, в дополнение к подготовленным операторам.

Your Common Sense 10.07.2019 16:12

@YourCommonSense Тогда я согласен с вашим утверждением.

GrumpyCrouton 10.07.2019 16:13
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
9
148
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

То, что вы сейчас делаете, это хешировать пароль (который вы экранировали первым; вы никогда не должны экранировать пароли, поскольку это изменяет хэш), а затем сопоставляете/проверяете его по сравнению со значением, которое вы только что хэшировали, без использования хэша из базы данных - так что это всегда будет соответствовать. Это эквивалент установки переменной $a = 'foo';, а затем проверки if ($a == 'foo') — проверка всегда будет возвращать значение true.

Вместо этого извлеките хешированное значение из базы данных на основе имени пользователя и используйте его в качестве второго аргумента для password_hash().

Также,

  • Не сравнивайте с хешем в базе данных, извлеките его, а затем пропустите password_verify()
  • Использовать подготовленные операторы (вместо стандартного метода query() и с использованием real_escape_string()) — см. Как я могу предотвратить внедрение SQL в PHP?
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $stmt = $db->prepare("SELECT passhash FROM qa_users WHERE handle = ?");
    $stmt->bind_param("s", $_POST['username']);
    $stmt->execute();
    $stmt->bind_result($hash);
    $stmt->fetch();

    if (password_verify($_POST['password'], $hash)) {
        echo "Valid login";
    } else {
        echo "Invalid login";
    }
    $stmt->close();
}

Примечание для OP: использование заполнителя ? и bind_param() известно как использование подготовленных операторов, это эффективно устраняет риск SQL-инъекций, а также означает, что вам не нужно очищать свои входные данные перед их использованием в запросе.

GrumpyCrouton 10.07.2019 15:47
«Не сравнивайте с хешем в базе данных, извлеките его, а затем запустите через password_hash()» Действительно, добавление хэш-пароля в WHERE может снова привести к возможному временные атаки, потому что базы данных предназначены для максимально быстрого возврата данных... Особенно, когда хэш-пароль включен в индекс, а алгоритм поиска Btree довольно стабилен во времени..
Raymond Nijland 10.07.2019 15:59

@RaymondNijland Мало того, хеш для каждого хэша разный, поэтому вы не получите совпадений, даже если пароль на самом деле правильный. Но да, это тоже!

Qirel 10.07.2019 16:02

действительно, я знаю, что @Qirel password_hash() защищает от радужных таблиц, а использование blowfish также защищает от грубой силы GPU (кластеров). Поскольку blowfish не работает быстро на процессорах и очень медленно работает на GPU, если вы можете заставить его работать.

Raymond Nijland 10.07.2019 16:05

Другие вопросы по теме