Проанализируйте уязвимость SQL-инъекции в PHP-фрагменте: "$q = \"SELECT * FROM users WHERE login='\".$_GET['login'].\"'\";" — опишите, как подготовленные выражения или ORM решают проблему, и предложите безопасную альтернативу с примерами

23 Мар в 09:50
43 +1
0
Ответы
1
Проблема
- В строке
$q = "SELECT * FROM users WHERE login='".$_GET['login']."'";
значение из $_GET вставляется в SQL напрямую — злоумышленник может подставить часть SQL и изменить смысл запроса (SQL‑инъекция). Пример полезной нагрузки: строка логина "x′OR′1′=′1""x' OR '1'='1""x′OR′1′=′1" превратит условие в нечто вроде `WHERE login='x' OR '1'='1'`, где ′1′=′1′'1'='1'′1′=′1′ всегда истинно, и вы вернёте все записи.
Почему подготовленные выражения/ORM решают проблему
- Подготовленные выражения (prepared statements) отправляют текст запроса и данные параметров отдельно. СУБД воспринимает параметры как данные, а не как часть SQL‑синтаксиса, поэтому попытки вставить операторы или кавычки не изменят структуру запроса.
- ORM (например, Eloquent, Doctrine) обычно использует параметризацию под капотом для методов типа where(), поэтому те же атаки не сработают, пока вы не вставляете сырые SQL-фрагменты вручную.
Безопасные альтернативы — примеры
1) PDO (рекомендуется)
- Пример с именованным параметром:
$pdo = new PDO($dsn, $user, $pass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$sql = "SELECT id, login, email FROM users WHERE login = :login";
$stmt = $pdo->prepare($sql);
$stmt->execute([':login' => $_GET['login']]);
$user = $stmt->fetch();
- Примечание: не используйте SELECT * для критичных запросов (минимизируйте возвращаемые поля).
2) MySQLi (процедурный/объектный интерфейс)
- Объектный пример:
$stmt = $mysqli->prepare("SELECT id, login FROM users WHERE login = ?");
$stmt->bind_param("s", $_GET['login']); // "s" — строка
$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();
3) ORM (пример Eloquent)
- Если у вас Laravel/Eloquent:
$user = User::where('login', $request->input('login'))->first();
- ORM сам выполнит безопасную привязку параметра.
Дополнительные меры безопасности (рекомендации)
- Валидация/вайтлист: проверяйте формат логина (разрешённые символы, длина). Это уменьшит риски и лишние данные.
- Минимизация привилегий: учётная запись БД должна иметь только нужные права (SELECT, INSERT и т.д.).
- Не полагайтесь только на экранирование функций вроде addslashes(); используйте параметризацию.
- Для авторизации сравнивайте хеши паролей (password_hash/password_verify), не выбирайте и не передавайте пароли в открытом виде.
- Логируйте и мониторьте неудачные попытки, применяйте ограничение частоты запросов.
Кратко: замените конкатенацию строки SQL на подготовленные выражения (PDO или mysqli) или используйте ORM‑вызовы — это предотвращает интерпретацию пользовательских данных как кода SQL.
23 Мар в 10:30
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир