Найдите уязвимость в этом SQL-подходе к аутентификации: query = "SELECT * FROM users WHERE login = '" + login + "' AND pass = '" + hash + "'"; — объясните виды атак, как их использовать, и приведите безопасные альтернативы в разных СУБД и ORM; обсудите также защиту от утечек через логи и ошибок конфигурации

31 Окт в 09:58
2 +2
0
Ответы
1
Кратко — это уязвимость типа SQL‑инъекции: конкатенация строк с входными данными позволяет злоумышленнику подменять структуру запроса и выполнять произвольные SQL‑операции (вход в чужой аккаунт, чтение/удаление данных и т. д.).
Почему именно: строковая сборка
query = "SELECT * FROM users WHERE login = '" + login + "' AND pass = '" + hash + "'";
вставляет непроверённые символы пользователя прямо в SQL, поэтому если в поле login придёт специальная нагрузка, итоговый SQL изменится.
Виды атак и примеры (как использовать)
- Аутентификация bypass (простая): подставить payload, который делает условие истинным:
login: ' OR '1'='1' --
Итоговый WHERE станет примерно: WHERE login = '' OR '1'='1' --' AND ...
(′1′=′1′'1'='1'1=1 — всегда истинно).
- Логическое/булево‑слепое извлечение: проверять по битам/символам значения из БД, например:
' OR (SUBSTR((SELECT pass FROM users WHERE login='admin'),1,1)='a') --
или time‑based через SLEEP:
' OR IF(SUBSTR((SELECT pass FROM users WHERE login='admin'),1,1)='a', SLEEP(5),0) --
(задержка 555 секунд сигнализирует об истинности).
- UNION‑инъекция (извлечение данных): закрыть логический фильтр и добавить UNION SELECT для чтения других таблиц.
- Stacked queries (несколько команд в одном запросе): ; DROP TABLE users; — работает если СУБД/драйвер разрешают множественные инструкции.
- Error‑based (через ошибки): вынудить БД выдать текст ошибки с нужными данными.
- Комментарии и обход фильтров: разные СУБД допускают разные комментарии (`--`, `#`, `/* ... */`).
Особенности по СУБД (кратко)
- MySQL: комментарий `-- ` (нужен пробел), `#`, поддерживает SLEEP(), часто допускает multi‑statements если включены.
- PostgreSQL: `--`, `/* */`, поддерживает pg_sleep().
- MSSQL: `--`, `/* */`, поддерживает `;` и часто multi‑statements; имеет WAITFOR DELAY для тайм‑задержки.
- Oracle: `--`, `/* */`, PL/SQL блоки; payloadы отличаются синтаксисом.
Безопасные альтернативы (рекомендуемые)
1) Параметризованные запросы / подготовленные выражения (bind parameters)
- PHP PDO:
$stmt = $pdo->prepare("SELECT * FROM users WHERE login = ? AND pass = ?");
$stmt->execute([$login, $hash]);
- Python (psycopg2 для PostgreSQL):
cur.execute("SELECT * FROM users WHERE login = %s AND pass = %s", (login, hash))
- Java JDBC:
PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE login = ? AND pass = ?");
ps.setString(1, login); ps.setString(2, hash);
- C# (SqlCommand):
cmd.CommandText = "SELECT * FROM users WHERE login = @login AND pass = @pass";
cmd.Parameters.AddWithValue("@login", login);
Важно: не вставлять значения в строку запроса вручную.
2) ORM‑абстракции (правильное использование)
- Django ORM:
user = User.objects.filter(login=login).first()
- SQLAlchemy:
session.query(User).filter(User.login == login).one_or_none()
- Entity Framework / Hibernate: использовать параметризованные LINQ/Criteria, не строить SQL вручную.
ORM безопасны при обычном использовании; опасны при вызове raw SQL без параметров.
3) Хранение паролей и сравнение
- Хранить только соль + сильный хеш: bcrypt, Argon2, PBKDF2 (предпочтительнее Argon2/bcrypt).
- Не сравнивать пароли в SQL. Лучший паттерн:
1. Выбрать хеш по логину: SELECT pass_hash, salt FROM users WHERE login = ?;
2. В приложении вычислить hashCandidate = bcrypt(password + salt) и сравнить безопасно (constant‑time).
- Использовать готовые библиотеки для проверки пароля (они уже делают constant‑time compare).
4) Ограничения на уровне БД и конфигурация
- Отключить multi‑statement (если не нужен).
- Выдавать приложению минимально необходимые привилегии (например, SELECT на таблице users).
- Включить аудит/логирование подозрительных запросов, но не логировать секреты.
- Применять WAF/IDS для обнаружения подозрительных паттернов.
Защита от утечек через логи и ошибки конфигурации
- Не логируйте сырые запросы с подставленными параметрами и тем более не логируйте пароли/хеши. Логируйте только метаданные (категория ошибки, временная метка, ID запроса), параметры — в маскированном виде.
- В логах и трассировках заменяйте/редактируйте чувствительные поля (masking/redaction).
- Не показывайте подробные SQL‑ошибки пользователю — используйте пользовательские страницы ошибок и централизованный сбор ошибок (с контролем доступа).
- Ограничьте уровень логирования в проде (ERROR/WARN вместо DEBUG).
- Контролируйте конфигурационные файлы: не держите в репозитории учетные данные, используйте секрет‑менеджер.
- Ротация и минимизация прав доступа: смена паролей/ключей, MFA для админов.
- Мониторинг/Alerting: аномальные запросы, частые проваленные логины, большие UNION/селекты — триггерить расследование.
Краткий чек‑лист защиты (порядок приоритетов)
- Использовать параметризованные запросы / ORM без raw SQL.
- Хранить пароли в виде bcrypt/Argon2 хешей, проверять в приложении.
- Минимальные привилегии для БД-пользователя.
- Отключить multi‑statements, если не нужны.
- Не логировать секреты; редактировать/маскировать параметры в логах.
- Не выводить стек‑трэйсы и подробные ошибки клиентам.
- Внедрить WAF, мониторинг и аудит.
Если нужно — пришлю конкретные примеры защищённого кода для выбранного языка/СУБД или демонстрации эксплойта (payload'ы) для вашей СУБД.
31 Окт в 10:50
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир