Индивидуальная проверка имени и пароля в PHP

Я пишу намеренно уязвимое веб-приложение. Я хотел бы выяснить, как проверить имя пользователя и пароль на соответствие базе данных и друг другу.

Итак: если имя пользователя существует в базе данных и пароль существует в базе данных, а имя пользователя и пароль принадлежат вместе. Я полностью знаю, как отправить запрос, который проверяет оба параметра одновременно и возвращает либо истину, либо ложь, поэтому, пожалуйста, не начинайте с этого. Моя цель - индивидуально проверить оба, чтобы я мог сообщить пользователю, какой из них не работает.

Вот мой код, но, поскольку я на самом деле не специалист по PHP, он явно не работает:

<?php 
if (isset($_POST["submit"])){
    $username = mysqli_real_escape_string($conn, $_POST['username']);
    $password = mysqli_real_escape_string($conn, $_POST['password']); 

    $sql_username = "SELECT id FROM users WHERE username = '$username'";
    $sql_password = "SELECT id FROM users WHERE password = '$password'";
    $result_username = mysqli_query($conn, $sql_username);
    $result_password = mysqli_query($conn, $sql_password);
    $row_username = mysqli_fetch_array($result_username);
    $row_password = mysqli_fetch_array($result_password);
    $count_username = mysqli_num_rows($result_username);
    $count_password = mysqli_num_rows($result_password);

    if ($count_username > 0 && $count_password < 0) {
        echo "Invalied password";
    } else if ($count_username < 0 && $count_password > 0) {
        echo "Invalied username";
    } else {
        "Welcome";
    }
}
?>

Какие-нибудь намеки?

Редактировать

Можно использовать $ conn, поскольку я получаю его из другого файла php.

ПРЕДУПРЕЖДЕНИЕ: Написать свой собственный уровень контроля доступа непросто, и есть много возможностей сделать это совершенно неправильно. Пожалуйста, не пишите свою собственную систему аутентификации, когда любой современный рамки разработки, такой как Laravel, имеет встроенный надежный система аутентификации. По крайней мере, следуйте рекомендуемые лучшие практики безопасности и никогда не храните пароли в виде простого текста или слабому хешу, например SHA1 или MD5.
tadman 01.07.2018 00:10

Примечание. Объектно-ориентированный интерфейс mysqli значительно менее подробен, что упрощает чтение и аудит кода, и его нелегко спутать с устаревшим интерфейсом mysql_query. Прежде чем вы слишком увлечетесь процедурным стилем, стоит переключиться на него. Пример: $db = new mysqli(…) и $db->prepare("…"). Процедурный интерфейс является артефактом эпохи PHP 4, когда был представлен API mysqli, и его не следует использовать в новом коде.

tadman 01.07.2018 00:10
ПРЕДУПРЕЖДЕНИЕ: при использовании mysqli вы должны использовать параметризованные запросы и bind_param для добавления пользовательских данных в свой запрос. НЕ использует для этого строковую интерполяцию или конкатенацию, потому что вы создали серьезный Ошибка SQL-инъекции. НИКОГДА помещает данные пользователя $_POST, $_GET или любой непосредственно в запрос, это может быть очень вредно, если кто-то попытается воспользоваться вашей ошибкой.
tadman 01.07.2018 00:10

Вы никогда проверяете пароль в базе данных, потому что, если вы можете выполнить сопоставление с открытым текстом, у вас уже проблемы. Хороший алгоритм хеширования паролей производит по существу случайный результат, но его можно проверить, если и только если у вас есть правильное «предположение». Правильная процедура - найти соответствующую пользовательскую строку, загрузить эти данные и проверить хэш с помощью password_verify.

tadman 01.07.2018 00:11

дорогой Тадман, большое спасибо за твои идеи. пожалуйста, игнорируйте все недостатки безопасности в моем коде и сосредоточьтесь на вопросе. Хотите верьте, хотите нет, но моя абсолютная цель - сделать приложение настолько уязвимым, насколько это возможно - отсюда и подробная пользовательская информация об имени пользователя и пароле. Спасибо.

Riwi 01.07.2018 00:13

Этот код позволит вам войти, если я введу «admin», который является пользователем, и «pass123», который является паролем для кто-нибудь. Это не проверяет правильность пароля администратора.

tadman 01.07.2018 00:13

Ни один из этих кодов не имеет смысла. Почему бы просто не впустить их, даже не пытаясь, если это цель? Реальный код входа в систему структурирован не так, поэтому я не уверен, что вы пытаетесь доказать, даже с академической точки зрения. Если бы вы могли лучше объяснить эту часть, мы, вероятно, могли бы заняться этим конкретно.

tadman 01.07.2018 00:14

это, к сожалению, неверно, этот код не дает никакой реакции на любой ввод. Я предполагаю, что он не может отправить более 1 запроса одним нажатием кнопки.

Riwi 01.07.2018 00:15

Это запускает два запроса на запрос. Не уверен, куда вы идете с этим. Если у вас есть одна строка с «admin» в качестве имени пользователя и другая, совершенно не связанная с этим строка с «pass123» в качестве пароля, то угадывание этой комбинации позволит войти.

tadman 01.07.2018 00:17
Стоит ли изучать 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 и хотите разрабатывать...
4
9
93
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий
    <?php
    //set up a connection and all that prerequisite stuff
    $sqlConnectionNameHere = new mysqli($sql_host, $sql_username, $sql_password, $sql_dbname);
    $username = 'bob'; //the username that will be checked
    $password = 'securepassword1'; //the password that will be checked
    $query = $sqlConnectionNameHere->query("SELECT username, password FROM users WHERE username='$username' LIMIT 1"); //make your query

    if ($query->num_rows != 1){ //if the datbase didn't return any rows, the user with $username must not exist
        die('User not found!');
    }

    while ($user = $query->fetch_assoc()){
        if ($user['password'] != $password){
            die('Invalid Password');
        }
    }

    //if they've made it here, the user exists and the password matches!

    echo 'Welcome!';
?>

Это действительно простой способ сделать это. Вы можете добавить к этому дополнительную безопасность.

Надеюсь это поможет. Удачи тебе!

Я знаю, что вы просто пытаетесь помочь, но эти быстрые решения создают больше проблем, чем решают.

tadman 01.07.2018 00:16

1. этот пример недействителен, потому что он повторно использует переменную $username для подключения и для проверки пользователем 2. в этом примере вводится SQL-инъекция

Iłya Bursov 02.07.2018 17:19

Я знаю, что это круче, чтобы пользователь знал, неверны ли имя пользователя или пароль. Но это на самом деле помогает нежелательным особям пройти этот тест. Поскольку они могут проверить, присутствует ли конкретный пользователь или нет. Оттуда этот человек может подобрать пароль. Поэтому рекомендуется просто проверить имя пользователя и пароль.

Кроме того, вы можете сохранить пароль в виде хеша. Таким образом, даже хост вашей базы данных не имеет прямого доступа к паролям. Используйте MD5 или SHA. Например, учетные данные в вашей базе данных будут выглядеть так:

User       Password
Admin      098f6bcd4621d373cade4e832627b4f6

Это хеш MD5. Вы получите этот хеш, если обработаете md5('test'). Хеш - это функция «шифрования» в одну сторону. Вы проверяете это путем хеширования пользовательского ввода и сравнения этого результата с сохраненным хешем.

Если вы проверите этот пароль, вы привяжете его следующим образом:

$stmt->bind_param("ss", $_POST['username'], md5($_POST['password']));

$mysqli = new mysqli("localhost", "my_user", "my_password", "my_db");

Открытый пароль (не рекомендуется!) - подготовленный выбор

$stmt = $mysqli->prepare("SELECT id FROM users WHERE username=? AND password=?");

// type string, string ("ss")
$stmt->bind_param("ss", $_POST['username'], $_POST['password']);

// hashed (recommended)
// $stmt->bind_param("ss", $_POST['username'], md5($_POST['password']));

$stmt->execute();

// set target for the id-column
$stmt->bind_result($id);

// Will be TRUE if a row has been found
if ( $stmt->fetch() ) {
    echo "Welcome! user:{$id}";
} else {
    echo "Invalid username or password";
}

Подробности смотрите на mysqli подготовить И еще немного, связанное с безопасностью: Хеширование паролей

Я ценю вашу заботу и помощь Пилану, но на самом деле причиной этого кода является представление уязвимостей. :) Спасибо за ваш вклад!

Riwi 01.07.2018 00:39

о :( - ну, теперь этот код общедоступен и будет скопирован - я могу спать лучше, если знаю, что здесь есть ответ, указывающий на это

SirPilan 01.07.2018 00:54

спать спокойно дружище :)

Riwi 01.07.2018 08:53

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