Возможна ли SQL-инъекция с mysqli_real_escape_string?

Есть ли способ использовать этот код и войти под конкретным именем пользователя (например, Сэм)? Функция mysqli_real_escape_string () экранирует все символы NUL (ASCII 0), \ n, \ r, \, ', "и Control-Z.

Я пробовал с username = "Sam" и domain = "' union (SELECT 1, 123456) # a", но это не работает ..

$user   = $_POST['user'];
$domain = $_POST['domain'];
$pwd    = $_POST['pwd'];

function login($username, $domain, $password) {
    global $vuln_db;
    $starttime = microtime(true);
    $username = mysqli_real_escape_string($vuln_db, trim($username));
    $domain   = mysqli_real_escape_string($vuln_db, trim($domain));
    $password = trim($password);
    if (empty($password) || empty($username) || empty($domain)) {
        return FALSE;
    }
    // We store the password in plaintext to keep the homework's code short.
    // For anything even remotely real, use a proper password storage scheme.
    $query = "SELECT user_id, password FROM users WHERE username = '$username' AND domain LIKE '$domain'";
    $result = mysqli_query($vuln_db, $query) or die(mysqli_error($vuln_db));
    if ($result) {
        $row = mysqli_fetch_row($result);
        if ($row) {
            $the_password = trim($row[1]);
            for($i = 0; $i < strlen($the_password); $i++) {
                /* Bruteforce is not the way! */
                usleep(100000);
                if ($password[$i] != $the_password[$i]) {
                    $endtime = microtime(true);
                    return FALSE;
                }
            }
            return TRUE;
        } else {
            return FALSE;
        }
    }
}

Могу ли я получить истину из этой функции с помощью SQL-инъекции или других методов?

Возможный дубликат SQL-инъекция, обходящая mysql_real_escape_string ()

Nigel Ren 29.05.2018 12:42

Лучше всего использовать подготовленное заявление вместо экранирования каждого параметра, чтобы упростить защиту ваших запросов. Но вы используете кавычки вокруг ваших строк, чтобы ваши переменные были в безопасности после экранирования.

AnthonyB 29.05.2018 12:52

Это упражнение по внедрению sql для университета, но я не могу найти способ войти в систему. Можно ли каким-то образом использовать глобальную переменную $ vuln_db?

keyblade95 29.05.2018 14:20

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

keyblade95 29.05.2018 14:27
Стоит ли изучать 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 и хотите разрабатывать...
2
4
957
1

Ответы 1

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

У экранирования есть ряд крайних случаев, когда он не работает, как описано в ответах на SQL-инъекция, обходящая mysql_real_escape_string (). Требуется тщательное обдумывание и тестирование, чтобы убедиться, что вы не реализуете код, уязвимый в одном из этих крайних случаев. Такое мышление и тестирование заставляют писать код дольше.

Вот почему в настоящее время рекомендуется использовать параметры запроса вместо экранирования строк.

$query = "SELECT user_id, password FROM users WHERE username = ? AND domain LIKE ?";
$stmt = mysqli_prepare($vuln_db, $query) or die(mysqli_error($vuln_db));
$stmt->bind_param('ss', $username, $domain);
$stmt->execute() or die(mysqli_error($vuln_db));
$result = $stmt->get_result() or die(mysqli_error($vuln_db));
  • Параметры запроса упрощают написание кода и упрощают его чтение.
  • Параметры запроса не имеют крайних случаев уязвимости, как при экранировании строки.

P.S .: Это не связано с вашим вопросом об экранировании, но вам также следует научиться использовать password_hash () и password_verify () вместо хранения паролей в виде обычного текста.

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