Проанализируйте уязвимый фрагмент серверного кода, формирующего SQL‑запрос через конкатенацию входных данных пользователя (например, запрос SELECT * FROM users WHERE name = ' + input), оцените риск SQL‑инъекции и возможные векторы эксплуатации, предложите безопасную реконструкцию кода с параметризованными запросами и дополнительными слоями защиты, и обсудите ограничения и случаи, где параметризация недостаточна

24 Окт в 14:28
5 +1
0
Ответы
1
Анализ уязвимого фрагмента
- Уязвимый пример: конкатенация пользовательского ввода в запросе, например
SELECT * FROM users WHERE name = ' + input
(в реальности чаще: "SELECT * FROM users WHERE name = '" + input + "'").
- Проблема: ввод пользователя попадает в синтаксис SQL без разделения данных и кода — позволяет модифицировать структуру запроса.
Оценка риска и векторы эксплуатации
- Риск: высокий — раскрытие/изменение/удаление данных, обход аутентификации, выполнение произвольных SQL-команд, потенциальное выполнение команд ОС (через расширения/уязвимые функции), привилегированное расширение доступа.
- Частые векторы:
- Boolean/union-based/exfiltration: ввод ′OR′1′=′1′' OR '1'='1'OR1=1 позволяет вернуть все строки.
- Stacked queries (если драйвер/СУБД поддерживает несколько команд): "; DROP TABLE users; --".
- Time-based blind: вызов функций задержки для извлечения данных побитно.
- Error-based: провокация ошибок для получения данных.
- Second‑order SQLi: сохранённый вредоносный ввод используется в другом контексте позже.
- Injection в динамические части запроса (ORDER BY, LIMIT, идентификаторы).
Безопасная реконструкция (параметризованные запросы)
- Общий принцип: отделять код запроса от данных, использовать подготовленные выражения (prepared statements) или параметризированные API.
Примеры (коротко):
- Node.js (pg):
const res = await client.query('SELECT * FROM users WHERE name = $1', [input]);
- Node.js (mysql2):
connection.execute('SELECT * FROM users WHERE name = ?', [input]);
- Python (psycopg2):
cur.execute("SELECT * FROM users WHERE name = %s", (input,))
- Java (JDBC):
PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE name = ?");
ps.setString(1, input);
ResultSet rs = ps.executeQuery();
- C# (SqlClient):
var cmd = new SqlCommand("SELECT * FROM users WHERE name = @name", conn);
cmd.Parameters.AddWithValue("@name", input);
Особые случаи (LIKE, идентификаторы, ORDER BY, LIMIT)
- LIKE: экранировать метасимволы и передавать параметр, например в PostgreSQL через replace/ESCAPE.
- Имена таблиц/столбцов, ORDER BY, LIMIT нельзя передать как параметры — использовать строгий allowlist/маппинг:
- Не делать: "... ORDER BY " + userSort
- Делать: сопоставить userSort к фиксированному набору допустимых колонок и подставлять только проверенные имена.
Дополнительные слои защиты
- Ограничение привилегий БД: аккаунт приложения имеет минимальные права (SELECT нужных таблиц, запрет DROP/ALTER).
- Отключить возможность нескольких statement в драйвере (например, mysql: multiStatements=false).
- Валидация и allowlist входных данных (ограничение длины, формат, тип).
- Экранирование специальных символов для специфичных контекстов (LIKE, JSON, regex).
- Использование ORM с проверенными API (и избегать raw SQL), но проверять генерируемые запросы.
- WAF/IDS, логирование и мониторинг аномалий, rate limiting.
- Хранить и тестировать на наличие second-order инъекций.
- Регулярное сканирование безопасности (DAST/SAST) и ревью кода.
Ограничения параметризации и случаи, где она недостаточна
- Нельзя параметризовать идентификаторы (имена таблиц/столбцов), части синтаксиса (ORDER BY, GROUP BY, LIMIT) — нужен allowlist/маппинг.
- Параметризация не защищает от логических ошибок приложения (например, некорректная бизнес‑логика).
- Если приложение сохраняет «чистый» вредоносный ввод и позже подставляет его в динамический SQL без параметров — second‑order SQLi остаётся возможной.
- Некоторые драйверы/конфигурации, разрешающие многостейтментные запросы, повышают риск; параметры не предотвращают выполнение дополнительных statement'ов, если драйвер позволяет их объединять.
- Вызовы динамического SQL на стороне БД (EXEC/EXECUTE, составление строк в хранимых процедурах) остаются уязвимыми, если внутри хранимой процедуры используется конкатенация — там также нужно использовать параметризацию/безопасные API.
- Специальные операторы (JSON, full-text search, regex) требуют внимательного экранирования/вручную контролируемой обработки; простая подстановка параметров может не покрыть все риски.
Краткий чеклист для безопасной реализации
- Использовать подготовленные выражения для всех входных данных.
- Валидировать/ограничивать формат и длину ввода.
- Использовать allowlist для динамических частей запроса.
- Минимизировать привилегии БД-пользователя.
- Отключить/запретить множественные запросы в одном вызове.
- Логировать и мониторить подозрительные запросы.
- Тестировать на SQLi (SAST/DAST, fuzzing).
Если нужно, могу показать конкретный исправленный фрагмент кода для вашей платформы/СУБД.
24 Окт в 14:51
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир