Веб‑функция на PHP формирует SQL‑запрос конкатенацией: $q = "SELECT * FROM users WHERE name='".$_GET['name']."'"; — опишите, как можно эксплуатировать эту уязвимость, какие последствия возможны, и какие практические меры (на уровне кода, архитектуры и БД) нужно принять для надёжной защиты
Уязвимость: строковая конкатенация запроса с пользовательским вводом позволяет SQL‑инъекции — атакующий вставляет в \($_GET['name']\) фрагменты SQL, меняющие логику запроса. Как можно эксплуатировать (основные техники и последствия) - Аутентификация/авторизация обход: превращают условие WHERE в всегда истинное (например, логическая подстановка типа 1=11=11=1), получают доступ к чужим аккаунтам. - Чтение данных (data exfiltration): вытягивание таблиц пользователей, паролей, персональных данных (SELECT, UNION‑подзапросы). - Модификация/удаление данных: INSERT/UPDATE/DELETE при наличии прав — порча или потеря данных. - Выполнение нескольких запросов (stacked queries), если СУБД и драйвер это поддерживают — создание/удаление объектов, вставка бекдоров. - Блайнд‑инъекции (boolean/time‑based): получение данных при закрытых ошибках через побочные каналы. - Эскалация до RCE/получения файлов на диск: через специальные функции СУБД (LOAD_FILE, SELECT INTO OUTFILE) — возможен вывод конфигураций и секретов. - Последствия: утечка ПДн, финансовые потери, компрометация инфраструктуры, репутационный и юридический урон. Практические меры — код (непосредственно) - Использовать подготовленные выражения (prepared statements) с привязкой параметров (PDO или mysqli). Пример на PDO: $stmt=$pdo−>prepare("SELECT∗FROMusersWHEREname=:name");$stmt−>execute([′:name′=>$GET[′name′]]);$rows=$stmt−>fetchAll(); \$stmt = \$pdo->prepare("SELECT * FROM users WHERE name = :name");\\ \$stmt->execute([':name' => \$_GET['name']]);\\ \$rows = \$stmt->fetchAll(); $stmt=$pdo−>prepare("SELECT∗FROMusersWHEREname=:name");$stmt−>execute([′:name′=>$GET[′name′]]);$rows=$stmt−>fetchAll();
- Никогда не собирать SQL конкатенацией с пользовательскими данными. - Валидация и whitelist: проверяйте формат/длину/символы входа (например, допустимые имена — только буквы/цифры). - Для полей поиска применяйте ограничение длины и экранирование при необходимости; параметризация для значений, а не для имен таблиц/столбцов. - Отключать возможность выполнения нескольких запросов в одном вызове (mysqli_multi_query/ PDO::MYSQL_ATTR_MULTI_STATEMENTS — запретить). - Не раскрывать детализированные SQL‑ошибки пользователю; логируйте их в защищённые логи. Практические меры — архитектура / процесс - Принцип наименьших привилегий: у веб‑приложения должен быть отдельный DB‑пользователь с минимально необходимыми правами (например, только SELECT для чтения). - Разделение ролей и сервисов: отдельный аккаунт/endpoint для операций администрирования. - WAF и фильтрация запросов на уровне сети приложения — как дополнительный барьер (но не замена подготовленным выражениям). - Логи и мониторинг запросов на аномалии, IDS/IPS, сигнализация на попытки инъекций. - Регулярные pentest/DAST/SAST и code review, CI‑сканы зависимостей. - Бэкапы и планы восстановления на случай порчи/удаления данных. Практические меры — настройки СУБД - Отключить опасные возможности: например, для MySQL — LOCAL_INFILELOCAL\_INFILELOCAL_INFILE если не нужен; запретить ненужные функции/плагины. - Ограничить права на создание файлов (OUTFILE) и выполнение системных функций. - Включить аудит/логирование SQL‑запросов и ошибок; хранить и анализировать логи. - Использовать роли и гранулированные привилегии (GRANT по минимальному набору). - Обновлять СУБД и драйверы; использовать TLS для соединений к БД. Дополнительно — обнаружение и реагирование - Ограничение скорости/рейтов, CAPTCHA для подозрительных форм. - Триггеры уведомлений при аномальных выборках (большие объёмы извлекаемых данных). - Регулярное тестирование приложений (включая blind‑sqli тесты) и обучение разработчиков безопасным практикам. Кратко: защищайтесь на трёх уровнях — код (prepared statements, валидация), архитектура/операции (минимальные привилегии, WAF, логирование, тесты) и СУБД‑конфигурация (ограничения возможностей, аудит). Это сочетание предотвращает эксплуатацию и минимизирует ущерб при возможном прорыве.
Как можно эксплуатировать (основные техники и последствия)
- Аутентификация/авторизация обход: превращают условие WHERE в всегда истинное (например, логическая подстановка типа 1=11=11=1), получают доступ к чужим аккаунтам.
- Чтение данных (data exfiltration): вытягивание таблиц пользователей, паролей, персональных данных (SELECT, UNION‑подзапросы).
- Модификация/удаление данных: INSERT/UPDATE/DELETE при наличии прав — порча или потеря данных.
- Выполнение нескольких запросов (stacked queries), если СУБД и драйвер это поддерживают — создание/удаление объектов, вставка бекдоров.
- Блайнд‑инъекции (boolean/time‑based): получение данных при закрытых ошибках через побочные каналы.
- Эскалация до RCE/получения файлов на диск: через специальные функции СУБД (LOAD_FILE, SELECT INTO OUTFILE) — возможен вывод конфигураций и секретов.
- Последствия: утечка ПДн, финансовые потери, компрометация инфраструктуры, репутационный и юридический урон.
Практические меры — код (непосредственно)
- Использовать подготовленные выражения (prepared statements) с привязкой параметров (PDO или mysqli). Пример на PDO:
$stmt=$pdo−>prepare("SELECT∗FROMusersWHEREname=:name");$stmt−>execute([′:name′=>$GET[′name′]]);$rows=$stmt−>fetchAll();
\$stmt = \$pdo->prepare("SELECT * FROM users WHERE name = :name");\\
\$stmt->execute([':name' => \$_GET['name']]);\\
\$rows = \$stmt->fetchAll();
$stmt=$pdo−>prepare("SELECT∗FROMusersWHEREname=:name");$stmt−>execute([′:name′=>$G ET[′name′]]);$rows=$stmt−>fetchAll(); - Никогда не собирать SQL конкатенацией с пользовательскими данными.
- Валидация и whitelist: проверяйте формат/длину/символы входа (например, допустимые имена — только буквы/цифры).
- Для полей поиска применяйте ограничение длины и экранирование при необходимости; параметризация для значений, а не для имен таблиц/столбцов.
- Отключать возможность выполнения нескольких запросов в одном вызове (mysqli_multi_query/ PDO::MYSQL_ATTR_MULTI_STATEMENTS — запретить).
- Не раскрывать детализированные SQL‑ошибки пользователю; логируйте их в защищённые логи.
Практические меры — архитектура / процесс
- Принцип наименьших привилегий: у веб‑приложения должен быть отдельный DB‑пользователь с минимально необходимыми правами (например, только SELECT для чтения).
- Разделение ролей и сервисов: отдельный аккаунт/endpoint для операций администрирования.
- WAF и фильтрация запросов на уровне сети приложения — как дополнительный барьер (но не замена подготовленным выражениям).
- Логи и мониторинг запросов на аномалии, IDS/IPS, сигнализация на попытки инъекций.
- Регулярные pentest/DAST/SAST и code review, CI‑сканы зависимостей.
- Бэкапы и планы восстановления на случай порчи/удаления данных.
Практические меры — настройки СУБД
- Отключить опасные возможности: например, для MySQL — LOCAL_INFILELOCAL\_INFILELOCAL_INFILE если не нужен; запретить ненужные функции/плагины.
- Ограничить права на создание файлов (OUTFILE) и выполнение системных функций.
- Включить аудит/логирование SQL‑запросов и ошибок; хранить и анализировать логи.
- Использовать роли и гранулированные привилегии (GRANT по минимальному набору).
- Обновлять СУБД и драйверы; использовать TLS для соединений к БД.
Дополнительно — обнаружение и реагирование
- Ограничение скорости/рейтов, CAPTCHA для подозрительных форм.
- Триггеры уведомлений при аномальных выборках (большие объёмы извлекаемых данных).
- Регулярное тестирование приложений (включая blind‑sqli тесты) и обучение разработчиков безопасным практикам.
Кратко: защищайтесь на трёх уровнях — код (prepared statements, валидация), архитектура/операции (минимальные привилегии, WAF, логирование, тесты) и СУБД‑конфигурация (ограничения возможностей, аудит). Это сочетание предотвращает эксплуатацию и минимизирует ущерб при возможном прорыве.