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

17 Фев в 15:59
15 +2
0
Ответы
1
Чем опасно
- В текущем коде строка SQL собирается конкатенацией с прямым использованием пользовательского ввода:
\(q = "SELECT * FROM users WHERE name='".$_GET['name']."'";\)
Это позволяет атакующему подставить в параметр произвольный SQL-код (SQL‑инъекция). Последствия: обход аутентификации, утечка/изменение/удаление данных, получение привилегий, выполнение вредоносных команд через БД.
Простой пример атаки
- Если запрос в URL: `?name=admin' OR '1'='1`
Получается SQL: `SELECT * FROM users WHERE name='admin' OR '1'='1'` — вернёт все строки (аутентификация может быть обойдена).
- Или `name=a'; DROP TABLE users; -- ` — если разрешены мультизапросы, это может удалить таблицу.
Как правильно исправить (рекомендация)
1) Использовать подготовленные выражения (prepared statements) с параметрами — это надёжно и просто.
Пример на PDO:
```
$pdo = new PDO($dsn, $user, $pass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$stmt = $pdo->prepare("SELECT * FROM users WHERE name = :name");
$stmt->execute(['name' => $_GET['name']]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
```
Пример на mysqli:
```
$stmt = $mysqli->prepare("SELECT * FROM users WHERE name = ?");
$stmt->bind_param('s', $_GET['name']);
$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();
```
2) Дополнительные меры (всегда в комбинации):
- Валидация/вочлистинг входных данных (если имя — только буквы, применить регулярное ограничение).
- Использовать минимально необходимые привилегии для учётной записи БД (не root).
- Не возвращать `SELECT *`, перечислять только нужные поля.
- Логирование подозрительных запросов и ограничение количества результатов.
- На выводе в HTML — экранировать данные (prevent XSS), но это не заменяет параметризацию для SQL.
3) Что не стоит полагаться как основное:
- Ручное экранирование (`mysqli_real_escape_string`) — работает, но менее надёжно и легко ошибочно применяется; предпочтительны подготовленные выражения.
Кратко: не конкатенируйте пользовательский ввод в SQL — используйте параметризованные запросы (prepared statements), валидацию и принцип наименьших привилегий.
17 Фев в 16:04
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир