Найдите уязвимость в этом PHP‑фрагменте: $q = "SELECT * FROM users WHERE id=".$_GET['id']; $r = mysqli_query($db,$q); — какие угрозы здесь присутствуют, как их эксплуатировать и как защитить код
Уязвимость: SQL‑инъекция — код подставляет необработанное значение из \($_GET['id']\) прямо в запрос: \(q = "SELECT * FROM users WHERE id=".$_GET['id'];\) Какие угрозы и последствия - Чтение всех строк / обход авторизации — возврат большего набора строк. - Экфильтрация данных (UNION‑/error‑/blind‑инъекции). - Изменение/удаление данных (если разрешены множественные запросы). - DoS (например, заставить запрос ждать функциями типа SLEEP). - Утечка структуры БД через ошибки, повышение привилегий при дальнейших уязвимостях. Примеры эксплойта (для тестирования): - Получить все записи: запрос GET параметр id=111 OR 1=11=11=1
- UNION‑экспфильтрация (примерно): id=000 UNION SELECT username, password FROM admin -- - Временная инъекция (слепая): id=111 AND SLEEP(555) — задержит ответ, если инъекция сработала - Стековые запросы (если включены multiple statements): id=111; DROP TABLE users; — опасно, но зависит от конфигурации Как защитить (рекомендации, в порядке предпочтения) 1) Параметризованные запросы (подготовленные выражения). Пример с mysqli: $q = "SELECT * FROM users WHERE id = ?"; $stmt = mysqli_prepare($db, $q); mysqli_stmt_bind_param($stmt, "i", $id); $id = $_GET['id']; mysqli_stmt_execute($stmt); $r = mysqli_stmt_get_result($stmt); 2) Валидация и приведение типов (быстрый фильтр для id): $id = (int)$_GET['id']; // или проверить ctype_digit $q = "SELECT * FROM users WHERE id=".$id; 3) Если по какой‑то причине нельзя подготовить — использовать экранирование и явные кавычки, но это менее надежно: $id = mysqli_real_escape_string($db, $_GET['id']); // лучше только для строковых значений и с кавычками в SQL 4) Дополнительные меры: - Использовать учетную запись БД с минимальными привилегиями (не root). - Отключить поддержку множественных запросов (multiple statements) на соединении/сервере. - Не выводить SQL‑ошибки пользователю (логировать их, но не показывать). - Вести аудит/логирование подозрительных параметров. Кратко: основная уязвимость — SQL‑инъекция; исправление — подготовленные выражения и валидация входа, минимизация привилегий и отключение multi‑statement.
\(q = "SELECT * FROM users WHERE id=".$_GET['id'];\)
Какие угрозы и последствия
- Чтение всех строк / обход авторизации — возврат большего набора строк.
- Экфильтрация данных (UNION‑/error‑/blind‑инъекции).
- Изменение/удаление данных (если разрешены множественные запросы).
- DoS (например, заставить запрос ждать функциями типа SLEEP).
- Утечка структуры БД через ошибки, повышение привилегий при дальнейших уязвимостях.
Примеры эксплойта (для тестирования):
- Получить все записи: запрос GET параметр
id=111 OR 1=11=11=1 - UNION‑экспфильтрация (примерно): id=000 UNION SELECT username, password FROM admin --
- Временная инъекция (слепая): id=111 AND SLEEP(555) — задержит ответ, если инъекция сработала
- Стековые запросы (если включены multiple statements): id=111; DROP TABLE users; — опасно, но зависит от конфигурации
Как защитить (рекомендации, в порядке предпочтения)
1) Параметризованные запросы (подготовленные выражения). Пример с mysqli:
$q = "SELECT * FROM users WHERE id = ?";
$stmt = mysqli_prepare($db, $q);
mysqli_stmt_bind_param($stmt, "i", $id);
$id = $_GET['id'];
mysqli_stmt_execute($stmt);
$r = mysqli_stmt_get_result($stmt);
2) Валидация и приведение типов (быстрый фильтр для id):
$id = (int)$_GET['id']; // или проверить ctype_digit
$q = "SELECT * FROM users WHERE id=".$id;
3) Если по какой‑то причине нельзя подготовить — использовать экранирование и явные кавычки, но это менее надежно:
$id = mysqli_real_escape_string($db, $_GET['id']);
// лучше только для строковых значений и с кавычками в SQL
4) Дополнительные меры:
- Использовать учетную запись БД с минимальными привилегиями (не root).
- Отключить поддержку множественных запросов (multiple statements) на соединении/сервере.
- Не выводить SQL‑ошибки пользователю (логировать их, но не показывать).
- Вести аудит/логирование подозрительных параметров.
Кратко: основная уязвимость — SQL‑инъекция; исправление — подготовленные выражения и валидация входа, минимизация привилегий и отключение multi‑statement.