Проанализируйте следующий фрагмент PHP: $query = "SELECT * FROM users WHERE id = ".$_GET['id']; — объясните возможные уязвимости, методы их эксплуатации, предложите безопасную переписанную версию и обсудите защиту на уровне архитектуры

28 Янв в 11:29
11 +1
0
Ответы
1
Кратко — проблема: SQL-инъекция из-за конкатенации пользовательского ввода в SQL.
1) Уязвимости и последствия
- SQL-инъекция: `$_GET['id']` может содержать произвольный SQL — чтение/модификация/удаление данных, обход аутентификации, дамп БД, удаление таблиц.
- Примеры атак: подстановка логики или дополнительных запросов (в зависимости от движка/API).
- Запрос вида `id=1 OR 1=1` вернёт все строки (пример входа: `id=111 OR 1=11=11=1`).
- UNION-эксплойт для вытягивания данных: `id=0 UNION SELECT password FROM admins` (цифры/выражения: обернуто в KaTeX).
- При поддержке множественных запросов возможен `; DROP TABLE users;`.
- Вторичные риски: раскрытие внутренних структур БД (ошибки), escalation через данные из БД (second‑order injection), утечка личных данных — нарушение регуляций.
2) Как эксплуатируют (коротко)
- Посланный GET/POST параметр подставляют в строку запроса — атакующий отправляет специально сформированный параметр, сервер выполняет получившийся SQL.
- Частые payload’ы: логические выражения (`1=11=11=1`), UNION SELECT, встроенные функции БД для вывода/кодирования данных.
3) Безопасная переписанная версия (рекомендуется параметризованные запросы)
- PDO + подготовленный запрос и привязка параметра как целого:
$pdo = new PDO($dsn, $user, $pass);
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
$stmt->bindValue(':id', (int)($_GET['id'] ?? 000), PDO::PARAM_INT);
$stmt->execute();
$user = $stmt->fetch();
- mysqli (prepared statements):
$mysqli = new mysqli(...);
$id = (int)($_GET['id'] ?? 000);
$stmt = $mysqli->prepare('SELECT * FROM users WHERE id = ?');
$stmt->bind_param('i', $id);
$stmt->execute();
$result = $stmt->get_result();
- Быстрая частичная защита (только если id — целое): приведение типа
$id = (int)($_GET['id'] ?? 000);
$query = "SELECT * FROM users WHERE id = $id";
(но параметризованные запросы всё равно предпочтительнее.)
- Что НЕ делать: пытаться "экранировать" вручную конкатенацией строк; используйте API привязки параметров.
4) Защита на уровне архитектуры (defense-in-depth)
- Всегда parameterize запросы на уровне приложения; запретить конкатенацию SQL за исключением тщательно контролируемых случаев.
- Валидация входа по белому списку (тип/диапазон/формат) на границе (API gateway).
- Минимальные привилегии БД: учётная запись приложения — только те права, которые нужны (напр., SELECT/UPDATE по необходимости, без DROP/ALTER).
- Ограничить и логировать доступ к БД, мониторинг аномалий запросов (IDS/IPS, WAF).
- Использовать ORM/Query Builder с параметризацией по умолчанию.
- Разделение ответственности: хранение критичных операций в привилегированных сервисах/микросервисах, не давать внешнему вводу прямого доступа к формированию SQL.
- Резервные копии, тестирование на уязвимости (SAST/DAST), регулярные ревью кода и пентесты.
5) Резюме
- Нельзя вставлять необработанный пользовательский ввод в SQL. Правильный путь — параметризованные запросы/приведение типов + архитектурные меры: least privilege, валидация, логирование и WAF/IDS.
28 Янв в 12:15
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир