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

25 Ноя в 11:47
2 +1
0
Ответы
1
Уязвимость
- В коде $query = "SELECT * FROM users WHERE name = '" . $_GET['name'] . "'"; — введённые пользователем данные вставляются в SQL напрямую → SQL‑инъекция. Злоумышленник может подменить структуру запроса.
Примеры атак (payload — что добавит злоумышленник)
- Авторизация обходом: запрос превращается в проверку всех строк: "' OR '1'='1' --" (ядро проверки 1=11=11=1).
- UNION‑инъекция для вытягивания данных: "' UNION SELECT credit_card,1 FROM payments --" (ядро использования 111 как столбца).
- Разрушение/удаление: "'; DROP TABLE users; --" — если разрешены несколько команд.
- Blind SQL injection: побитовое/логическое угадывание данных через время/ошибки (например, payload типа "' AND IF(SUBSTRING(password,1,1)='a', SLEEP(5), 0) --").
- Использование кодировок/обхода фильтров: экранирование, комментарии, байтовые последовательности.
Последствия: утечка/изменение/удаление данных, обход авторизации, удалённое выполнение административных SQL‑команд.
Способы защиты (по приоритету)
1. Параметризованные запросы (prepared statements) — основной и обязательный способ.
- PDO:
$pdo = new PDO(..., [PDO::ATTR_EMULATE_PREPARES => false]);
$stmt = $pdo->prepare("SELECT * FROM users WHERE name = :name");
$stmt->execute([':name' => $_GET['name']]);
- mysqli:
$stmt = $mysqli->prepare("SELECT * FROM users WHERE name = ?");
$stmt->bind_param("s", $_GET['name']);
$stmt->execute();
Пояснение: параметры передаются отдельно от текста запроса, нельзя изменить структуру SQL.
2. Валидация и нормализация входа (white‑list):
- Для имён — разрешить только буквы, пробелы и максимум N символов: проверка по регулярному выражению, ограничение длины.
Пример: if (!preg_match('/^[\p{L}\- ]{1,100}$/u', $name)) { /* reject */ }
- Для числовых полей — явно приводить к числу: $id = (int)$_GET['id'].
Пояснение: whitelist над blacklist — надёжнее.
3. Экранирование (как вторичный метод):
- mysqli_real_escape_string — уменьшает риск, но не заменяет подготовленные выражения. Использовать только если параметризованные запросы невозможны.
4. Отключить возможность выполнения нескольких запросов в одном вызове:
- Не использовать mysqli_multi_query; в PDO по умолчанию многозапросы не выполняются.
5. Минимизация прав БД:
- Аккаунт приложения должен иметь только необходимые права (SELECT/INSERT/UPDATE и т. п.), не должен иметь DROP/DELETE без нужды.
6. Настройки PDO:
- Отключить эмуляцию подготовленных выражений: PDO::ATTR_EMULATE_PREPARES = false (чтобы реальные prepared statements использовались сервером).
7. Защита на уровне приложений и инфраструктуры:
- Логи и мониторинг подозрительных запросов.
- Web Application Firewall (WAF) как дополнительный барьер.
- Прячьте подробные сообщения об ошибках от пользователя.
Короткая демонстрация безопасного кода (PDO):
$pdo = new PDO($dsn, $user, $pass, [PDO::ATTR_EMULATE_PREPARES => false]);
$name = $_GET['name']; // лучше пройти валидацию
$stmt = $pdo->prepare("SELECT id, name, email FROM users WHERE name = :name");
$stmt->execute([':name' => $name]);
$user = $stmt->fetch();
Резюме
- Самое важное: никогда не вставлять сырые данные в SQL — используйте подготовленные выражения + валидацию (whitelist и ограничение длины) + минимальные права у БД.
25 Ноя в 12:32
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир