Исследуйте уязвимость веб-приложения к SQL-инъекции: приведите пример вредоносного входа, объясните, как он эксплуатируется, и опишите многоуровневую стратегию защиты (параметризованные запросы, ORM, валидация, ограничение прав)
Пример вредоносного входа (для поля логина/пароля): - Аутентификация (bypass): `' OR 'a'='a' -- ` - Вытягивание данных (UNION): `' UNION SELECT username, password FROM users -- ` - Блайнд (по содержимому, без цифр в примере): `' AND (SELECT SUBSTRING(password,1,1) FROM users LIMIT 1) = 'a' -- ` Как это эксплуатируется (кратко): - Если код собирает SQL как строку, например: SELECT * FROM users WHERE username = '$username' AND password = '$password' и подставляет в него значение `'$username' = 'admin'` и вредоносный `'$password' = ' ' OR 'a'='a' -- '`, итоговый запрос превращается в логическое тавтологическое выражение и авторизация обходится. - UNION-пэйлоад добавляет свою выборку в результат основного запроса и позволяет вытянуть столбцы таблицы users. - Блайнд-инъекция позволяет по логическим проверкам или задержкам узнать данные, не получая их напрямую. Многоуровневая стратегия защиты (ключевые уровни): 111 Параметризованные запросы (prepared statements) - Всегда использовать параметризованные запросы вместо конкатенации строк. - Пример (Python psycopg2): cursor.execute("SELECT * FROM users WHERE username = %s AND password = %s", (username, password)) - Пример (PHP PDO): $stmt = $pdo->prepare("SELECT * FROM users WHERE username = :u AND password = :p"); $stmt->execute([':u' => $username, ':p' => $password]); 222 ORM с осторожностью - ORM (например, SQLAlchemy, Entity Framework, Hibernate) по умолчанию генерирует параметризованные запросы и снижает риск, но риск остаётся при использовании «сырого» SQL через ORM. - Избегать динамического составления SQL внутри ORM; использовать привязанные параметры и методы API. 333 Валидция и нормализация входа - Применять allowlist (разрешённые форматы), проверять типы, длины, набор символов; блокировать неожиданные управляющие символы. - Для полей, которые должны быть числовыми, приводить/валидировать в тип (int) на стороне сервера, не полагаться на клиентский JS. - Экранировать/кодировать вывод (output encoding) при отображении данных в HTML. 444 Ограничение прав и сегментация БД (least privilege) - Приложение должно подключаться под пользователем с минимально необходимыми привилегиями (например, только SELECT/INSERT/UPDATE на нужные таблицы), без прав DROP/ALTER/GRANT. - Отдельные учетные записи для операций администрирования и для приложения. Дополнительные меры (дополняют выше): - WAF / фильтрация на границе (Web Application Firewall) для блокировки известных шаблонов атак. - Логирование и мониторинг подозрительных запросов, оповещения при аномалиях. - Регулярные код‑аудиты и автоматические тесты (SAST, DAST, тесты на SQLi). - Применение механизма лимитов и задержек (rate limiting) и защита от брутфорса. Краткая рекомендация: базовая обязанность — убрать конкатенацию SQL и везде использовать параметризованные запросы; остальные слои (валидация, ограничения прав, ORM, мониторинг) служат дополнительной защитой и сокращают риск даже при ошибках в коде.
- Аутентификация (bypass): `' OR 'a'='a' -- `
- Вытягивание данных (UNION): `' UNION SELECT username, password FROM users -- `
- Блайнд (по содержимому, без цифр в примере): `' AND (SELECT SUBSTRING(password,1,1) FROM users LIMIT 1) = 'a' -- `
Как это эксплуатируется (кратко):
- Если код собирает SQL как строку, например:
SELECT * FROM users WHERE username = '$username' AND password = '$password'
и подставляет в него значение `'$username' = 'admin'` и вредоносный `'$password' = ' ' OR 'a'='a' -- '`,
итоговый запрос превращается в логическое тавтологическое выражение и авторизация обходится.
- UNION-пэйлоад добавляет свою выборку в результат основного запроса и позволяет вытянуть столбцы таблицы users.
- Блайнд-инъекция позволяет по логическим проверкам или задержкам узнать данные, не получая их напрямую.
Многоуровневая стратегия защиты (ключевые уровни):
111 Параметризованные запросы (prepared statements)
- Всегда использовать параметризованные запросы вместо конкатенации строк.
- Пример (Python psycopg2):
cursor.execute("SELECT * FROM users WHERE username = %s AND password = %s", (username, password))
- Пример (PHP PDO):
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = :u AND password = :p");
$stmt->execute([':u' => $username, ':p' => $password]);
222 ORM с осторожностью
- ORM (например, SQLAlchemy, Entity Framework, Hibernate) по умолчанию генерирует параметризованные запросы и снижает риск, но риск остаётся при использовании «сырого» SQL через ORM.
- Избегать динамического составления SQL внутри ORM; использовать привязанные параметры и методы API.
333 Валидция и нормализация входа
- Применять allowlist (разрешённые форматы), проверять типы, длины, набор символов; блокировать неожиданные управляющие символы.
- Для полей, которые должны быть числовыми, приводить/валидировать в тип (int) на стороне сервера, не полагаться на клиентский JS.
- Экранировать/кодировать вывод (output encoding) при отображении данных в HTML.
444 Ограничение прав и сегментация БД (least privilege)
- Приложение должно подключаться под пользователем с минимально необходимыми привилегиями (например, только SELECT/INSERT/UPDATE на нужные таблицы), без прав DROP/ALTER/GRANT.
- Отдельные учетные записи для операций администрирования и для приложения.
Дополнительные меры (дополняют выше):
- WAF / фильтрация на границе (Web Application Firewall) для блокировки известных шаблонов атак.
- Логирование и мониторинг подозрительных запросов, оповещения при аномалиях.
- Регулярные код‑аудиты и автоматические тесты (SAST, DAST, тесты на SQLi).
- Применение механизма лимитов и задержек (rate limiting) и защита от брутфорса.
Краткая рекомендация: базовая обязанность — убрать конкатенацию SQL и везде использовать параметризованные запросы; остальные слои (валидация, ограничения прав, ORM, мониторинг) служат дополнительной защитой и сокращают риск даже при ошибках в коде.