English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Инъекции SQL (Injection)

В этом руководстве вы узнаете, как исправить распространенные уязвимости базы данных.

Что такое SQL-инъекция?

SQL-инъекция - это атака, при которой атакующий может вводить или выполнять вредоносный SQL-код в данные,传入ые из браузера в сервер приложения (например, из ввода веб-формы).

ее можно использовать для公开 конфиденциальной информации, такой как контактные данные пользователей, адреса электронной почты, информация о кредитных картах и т.д. Атакующий также может использовать ее для обхода процесса аутентификации и получения доступа ко всей базе данных. Давайте посмотрим, как это работает.

Как работает SQL-инъекция

рассмотрим следующий SQL-запрос, который является простым примером аутентификации пользователей с использованием имени пользователя и пароля в веб-приложении.

SELECT * FROM users WHERE username='username_val' AND password='password_val';

здесь,username_valиpassword_valкоторые представляют собой введенные пользователем имя пользователя и пароль. Если пользователь вводит такие значения, как 'john' в качестве имени пользователя и '123' в качестве пароля, то результативное предложение будет:

SELECT * FROM users WHERE username='john' AND password='123';

но предположим, если пользователь является атакующим, он не вводит действительное имя пользователя и пароль в поле ввода, а вводит что-то подобное следующему: ' OR 'x'='x

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

SELECT * FROM users WHERE username='' OR 'x'='x' AND password='' OR 'x'='x';

это действительный SQL-запрос, так как WHERE 'x'='x' всегда возвращает true, поэтому запрос вернетпользователивсе строки в таблице. Вы можете видеть, что攻击ер может легко получить доступ ко всем конфиденциальным данным базы данных с помощью маленькой хитрости.

еслипользователиЕсли таблица很大 и содержит несколько миллионов строк, этот один запрос также может привести к атаке на отказ в обслуживании (DoS-атаке), сделав ваше приложение недоступным для легитимных пользователей.

Предупреждение:Если ваш скрипт создаетDELETEилиUPDATEЕсли вы выполняете запрос, игнорируя последствия уязвимости SQL-инъекции, это может быть еще хуже. Attackers могут удалить данные из таблицы или навсегда изменить все строки.

Предотвращение SQL-инъекций

Всегда проверяйте ввод пользователя, не делайте никаких предположений. Никогда не создавайте SQL-запросы, используя ввод пользователя напрямую. Если вы используете PHP и MySQL, вы можете использовать функцию mysqli_real_escape_string() для создания законных строк SQL, которые можно использовать в SQL-запросах.

Это очень базовый пример использования PHP и MySQL для проверки подлинности пользователей, который демонстрирует, как предотвращать SQL-инъекции при получении ввода от пользователя.

<?php
// Начало сеанса
session_start();
 
/* Попытка подключения к серверу MySQL. */
   Предположим, что вы запускаете сервер MySQL с использованием стандартных настроек (пользователь 'root' не имеет пароля) */
$link = mysqli_connect("localhost", "root", "", "demo");
 
// Проверка подключения
if($link === false){
    die("Ошибка: Невозможно подключиться к базе данных.");
}
 
// Обработка ввода пользователя для обеспечения безопасности
$username_val = mysqli_real_escape_string($link, $_POST['username']);
$password_val = mysqli_real_escape_string($link, $_POST['password']);
 
if(isset($username_val, $password_val)){
    // Попытка выбора выполнения запроса
    $sql = "SELECT * FROM users WHERE username='" . $username_val . "' AND password='" . $password_val . "'";
    if($result = mysqli_query($link, $sql)){
        if(mysqli_num_rows($result) == 1){
            // Пользователь уже прошел проверку подлинности, пожалуйста, выполните операцию здесь
            $row = mysqli_fetch_array($result);
            /*保存会话变量中的值,
               чтобы можно было в будущем ссылаться на него в том же сеансе.
            $_SESSION['user_id'] = $row['user_id'];
            $_SESSION['first_name'] = $row['first_name'];
            header('Location: welcome.html');
        }
            echo "Ошибка! Неверное имя пользователя или пароль.";
        }
    }
        echo "Ошибка: что-то пошло не так. Пожалуйста, попробуйте еще раз.";
    }
}
 
// Закрыть соединение
mysqli_close($link);
?>

Совет:Тестирование размеров и типов или содержимого переданных данных приложения, и внедрение соответствующих ограничений для предотвращения использования системных ресурсов.