Почему использование прямых SQL-запросов (mysql_query) в коде без очистки входных данных ведет к SQL-инъекциям?

SQL-инъекция — одна из наиболее распространённых и опасных уязвимостей веб-приложений. Она возникает тогда, когда пользовательские данные напрямую подставляются в SQL-запрос без какой-либо проверки или экранирования.

**Как это работает на практике**

Представьте типичный код на PHP с использованием устаревшей функции mysql_query:

php
$username = $_GET[‘username’];
$query = «SELECT * FROM users WHERE username = ‘$username'»;
$result = mysql_query($query);

Если пользователь введёт в поле имени строку вида `’ OR ‘1’=’1`, итоговый запрос примет вид:

sql
SELECT * FROM users WHERE username = » OR ‘1’=’1′

Условие `’1’=’1’` всегда истинно, поэтому запрос вернёт все записи из таблицы пользователей. Злоумышленник получает доступ к данным, которые ему не предназначены.

**Почему mysql_query особенно уязвима**

Функция `mysql_query` (и весь модуль `mysql_*` в PHP) была признана устаревшей ещё в PHP 5.5 и полностью удалена в PHP 7. Она не поддерживает подготовленные выражения (prepared statements), которые являются основным механизмом защиты от SQL-инъекций. Разработчик вынужден вручную экранировать данные, что легко забыть или сделать неправильно.

**Что может сделать злоумышленник через SQL-инъекцию**

— Получить доступ к конфиденциальным данным: паролям, email-адресам, платёжным данным.
— Изменить или удалить данные в базе.
— Обойти аутентификацию и войти под любым пользователем, включая администратора.
— В некоторых конфигурациях — выполнить команды на уровне операционной системы через функции вроде `LOAD_FILE` или `INTO OUTFILE`.
— Провести атаку на другие системы, используя сервер БД как плацдарм.

**Как правильно защититься**

1. **Использовать подготовленные выражения (PDO или MySQLi):** Данные и SQL-код передаются раздельно, поэтому СУБД не может интерпретировать пользовательский ввод как часть запроса.

php
$stmt = $pdo->prepare(«SELECT * FROM users WHERE username = ?»);
$stmt->execute([$username]);

2. **Валидировать входные данные:** Проверять тип, длину и формат данных до их использования.

3. **Использовать ORM:** Фреймворки вроде Eloquent или Doctrine автоматически экранируют запросы.

4. **Принцип минимальных привилегий:** Пользователь базы данных должен иметь только те права, которые необходимы для работы приложения.

5. **Не отображать SQL-ошибки пользователю:** Это лишает злоумышленника ценной информации о структуре базы.

**Вывод**

Прямая подстановка пользовательских данных в SQL-запрос — это архитектурная ошибка, а не просто небрежность. Современные инструменты (PDO, MySQLi с prepared statements) полностью решают эту проблему, и их использование является обязательным стандартом разработки безопасных приложений.


Задайте вопрос нейросети

Не нашли ответ? Спросите ИИ — он подготовит развёрнутую статью.