Разберите уязвимость SQL-инъекции на примере PHP-кода: $query = "SELECT * FROM users WHERE name = '".$_GET['user']."'"; — как и почему это опасно, как исправить и какие общие практики предотвращения инъекций существуют

1 Июн в 14:40
9 +1
0
Ответы
1
Почему опасно (коротко)
- В коде происходит конкатенация пользовательского ввода в текст SQL-запроса:
$query="SELECT∗FROMusersWHEREname=′".__."′"; \text{\$query} = "SELECT * FROM users WHERE name = '" . \_\_ . "'"; $query="SELECTFROMusersWHEREname=".__.""; При этом СУБД видит строку целиком и не отличает данные от кода — злоумышленник может подставить фрагмент SQL и изменить смысл запроса.
- Последствия: чтение чужих записей, обход аутентификации, модификация или удаление данных, исполнение административных команд, получение доступа к серверу.
Пример эксплуатации
- Если пользователь передаст в \($_GET['user']\) значение:
′′OR′1′=′1′'' OR '1'='1'′′OR1=1 или "′OR′1′=′1""' OR '1'='1""OR1=1",
то итоговый запрос станет:
SELECT * FROM users WHERE name = '' OR '1'='1'
и вернёт все строки (логический трюк 1=11=11=1).
- Если передать "′;DROPTABLEusers;−−""'; DROP TABLE users; --"";DROPTABLEusers;", получится:
SELECT * FROM users WHERE name = ''; DROP TABLE users; --'
— что может удалить таблицу.
Как исправить (рекомендации и примеры)
1) Использовать подготовленные выражения (parameterized queries). Пример PDO:
$pdo = new PDO(...);
$stmt = $pdo->prepare("SELECT * FROM users WHERE name = ?");
$stmt->execute([$_GET['user']]);
$user = $stmt->fetch();
Параметры передаются отдельно — СУБД трактует их как данные, а не как часть SQL.
2) Или MySQLi с привязкой:
$stmt = $mysqli->prepare("SELECT * FROM users WHERE name = ?");
$stmt->bind_param("s", $_GET['user']);
$stmt->execute();
$res = $stmt->get_result();
3) Если нельзя использовать подготовленные выражения, как минимум экранировать:
$safe = $mysqli->real_escape_string($_GET['user']);
$query = "SELECT * FROM users WHERE name = '$safe'";
Но это хуже, требует аккуратности и правильной кодировки — предпочтительнее подготовленные запросы.
4) Для LIKE нужно экранировать спецсимволы (%, _) и передавать параметр в prepared statement.
Общие практики предотвращения SQL-инъекций
- Всегда использовать параметризованные запросы / подготовленные выражения.
- Применять принцип наименьших привилегий: учётная запись БД должна иметь только нужные права (SELECT/INSERT и т. д.).
- Валидация и белые списки для входных данных там, где возможно (например, числовые id — привести к целому).
- Не хранить в SQL-составе необработанные идентификаторы/имена таблиц; если нужно, проверять по белому списку.
- Логирование подозрительных запросов и мониторинг аномалий.
- Регулярные обновления СУБД/Драйверов, применение WAF как дополнительный уровень защиты.
- Использование ORM/Query Builder уменьшает риск, но не заменяет параметризацию при ручных запросах.
- Кодирование вывода и защита от XSS/CSRF — сопутствующие меры безопасности.
Коротко: никогда не вставляйте напрямую \($_GET\) или любой другой пользовательский ввод в SQL — используйте подготовленные запросы и принцип наименьших привилегий.
1 Июн в 14:46
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир