Найдите уязвимость и предложите исправление в SQL‑запросе на PHP: "$sql = \"SELECT * FROM users WHERE name='\".$_GET['name'].\"'\";" — какие типы атак возможны, как защититься на уровне кода и инфраструктуры
Уязвимость: конкатенация пользовательского ввода в SQL — SQL‑инъекция. Пример атаки (вставив в параметр name строку вида "' OR 'x'='x") подставит в запрос логическое условие, позволяющее вернуть все записи или выполнить произвольные изменения/удаления, получить доступ к данным, обойти аутентификацию и т.д. Возможные типы атак: - Прямые SQL‑инъекции (вставка условий, UNION‑вставки). - Blind / Boolean‑based / Time‑based инъекции. - Stacked queries (если СУБД/драйвер поддерживает несколько запросов). - Second‑order инъекции (ввод сохраняется и используется позже). - Вытекание данных через ошибки (информация об ошибках). - Комбинации с XSS/CSRF при последующей обработке вводимых данных. Защита на уровне кода (порядок важности): 1) Параметризованные запросы (prepared statements). Пример на PDO: $pdo = new PDO($dsn, $user, $pass, $opts); $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $stmt = $pdo->prepare("SELECT * FROM users WHERE name = :name"); $stmt->execute([':name' => $_GET['name']]); $user = $stmt->fetch(); или на mysqli: $stmt = $mysqli->prepare("SELECT * FROM users WHERE name = ?"); $stmt->bind_param("s", $_GET['name']); $stmt->execute(); 2) Валидация и ограничение входных данных: белый список символов, проверка длины (например не больше 505050 символов), типы данных: $name = $_GET['name']; if (!preg_match('/^[\p{L}\p{N}_-]+$/u', $name) || mb_strlen($name) > 505050) { /* reject */ } 3) Экранирование как запасной вариант (не рекомендуется вместо prepared statements): $name_esc = $mysqli->real_escape_string($_GET['name']); 4) Корректная обработка ошибок — не показывать SQL‑стек/сообщения пользователю. Защита на уровне инфраструктуры: - Принцип наименьших привилегий: учётная запись БД с правами только на нужные операции (SELECT на таблицу users и т.д.). - Отключить поддержку множественных запросов/stacked statements в драйвере/СУБД. - Web Application Firewall (WAF) для отлова известных payload‑ов и аномалий. - Логи, мониторинг запросов, алерты на аномалии (необычные SELECT/UNION/длительные запросы). - Сетевая сегментация БД, шифрование соединений, регулярные бэкапы и патчи. - Код‑ревью, автоматические сканеры на SQL‑инъекции (SAST/DAST). Короткое исправление (лучший вариант): заменить конкатенацию на подготовленный запрос (PDO или mysqli), добавить валидацию и снизить привилегии БД.
Возможные типы атак:
- Прямые SQL‑инъекции (вставка условий, UNION‑вставки).
- Blind / Boolean‑based / Time‑based инъекции.
- Stacked queries (если СУБД/драйвер поддерживает несколько запросов).
- Second‑order инъекции (ввод сохраняется и используется позже).
- Вытекание данных через ошибки (информация об ошибках).
- Комбинации с XSS/CSRF при последующей обработке вводимых данных.
Защита на уровне кода (порядок важности):
1) Параметризованные запросы (prepared statements). Пример на PDO:
$pdo = new PDO($dsn, $user, $pass, $opts);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$stmt = $pdo->prepare("SELECT * FROM users WHERE name = :name");
$stmt->execute([':name' => $_GET['name']]);
$user = $stmt->fetch();
или на mysqli:
$stmt = $mysqli->prepare("SELECT * FROM users WHERE name = ?");
$stmt->bind_param("s", $_GET['name']);
$stmt->execute();
2) Валидация и ограничение входных данных: белый список символов, проверка длины (например не больше 505050 символов), типы данных:
$name = $_GET['name'];
if (!preg_match('/^[\p{L}\p{N}_-]+$/u', $name) || mb_strlen($name) > 505050) { /* reject */ }
3) Экранирование как запасной вариант (не рекомендуется вместо prepared statements):
$name_esc = $mysqli->real_escape_string($_GET['name']);
4) Корректная обработка ошибок — не показывать SQL‑стек/сообщения пользователю.
Защита на уровне инфраструктуры:
- Принцип наименьших привилегий: учётная запись БД с правами только на нужные операции (SELECT на таблицу users и т.д.).
- Отключить поддержку множественных запросов/stacked statements в драйвере/СУБД.
- Web Application Firewall (WAF) для отлова известных payload‑ов и аномалий.
- Логи, мониторинг запросов, алерты на аномалии (необычные SELECT/UNION/длительные запросы).
- Сетевая сегментация БД, шифрование соединений, регулярные бэкапы и патчи.
- Код‑ревью, автоматические сканеры на SQL‑инъекции (SAST/DAST).
Короткое исправление (лучший вариант): заменить конкатенацию на подготовленный запрос (PDO или mysqli), добавить валидацию и снизить привилегии БД.