Что такое SQL Injection второго порядка (Second-Order) и как от нее защититься при повторном использовании данных из БД?
SQL Injection второго порядка (Second-Order SQL Injection) — это разновидность SQL-инъекции, при которой вредоносный код не выполняется в момент первоначального ввода данных, а сохраняется в базе данных и активируется позже, когда эти данные извлекаются и повторно используются в SQL-запросах без должной обработки.
## Как работает атака
Классическая SQL-инъекция срабатывает немедленно — вредоносный ввод попадает в запрос и исполняется. Second-Order атака устроена иначе:
1. **Этап сохранения**: злоумышленник вводит данные, например, имя пользователя `admin’—`. Приложение корректно экранирует строку при первичной вставке в БД, и данные сохраняются безопасно.
2. **Этап активации**: позже приложение извлекает это значение из БД и использует его в новом SQL-запросе — уже без повторного экранирования, считая данные из БД «доверенными». В этот момент инъекция срабатывает.
Пример уязвимого сценария: пользователь регистрируется с именем `admin’—`. При смене пароля приложение строит запрос:
sql
UPDATE users SET password=’новый_пароль’ WHERE username=’admin’—‘
Комментарий `—` отсекает условие `WHERE`, и пароль меняется у пользователя `admin`, а не у злоумышленника.
## Почему это особенно опасно
— Атака **не обнаруживается стандартными WAF** и сканерами, проверяющими только входящий трафик.
— Данные в БД выглядят безобидно и проходят проверки безопасности.
— Временной разрыв между сохранением и эксплуатацией затрудняет диагностику.
## Методы защиты
### 1. Параметризованные запросы (Prepared Statements)
Главное правило: **всегда** используйте параметризованные запросы или хранимые процедуры, независимо от источника данных — пользовательский ввод или данные из БД.
python
cursor.execute(«UPDATE users SET password=%s WHERE username=%s», (new_password, username_from_db))
### 2. Никогда не доверяйте данным из БД
Данные, извлечённые из базы, должны проходить ту же обработку, что и пользовательский ввод. Принцип «данные из БД безопасны» — ложный и опасный.
### 3. ORM с корректной настройкой
Использование ORM (SQLAlchemy, Hibernate, Django ORM) снижает риск, так как они автоматически параметризуют запросы. Однако избегайте raw-запросов внутри ORM без параметров.
### 4. Валидация и нормализация данных при сохранении
Ограничивайте допустимые символы на этапе регистрации и ввода: запрещайте кавычки, спецсимволы там, где они семантически не нужны.
### 5. Принцип минимальных привилегий
Аккаунт БД, используемый приложением, должен иметь только необходимые права — это ограничит ущерб при успешной атаке.
### 6. Аудит и логирование
Отслеживайте аномальные SQL-запросы и регулярно проводите code review с фокусом на места, где данные из БД подставляются в новые запросы.
### 7. Статический анализ кода (SAST)
Инструменты типа Semgrep, Checkmarx, SonarQube умеют находить паттерны Second-Order инъекций при правильной настройке правил.
## Итог
Second-Order SQL Injection эксплуатирует ложное доверие к данным из собственной базы данных. Единственная надёжная защита — параметризация абсолютно всех SQL-запросов вне зависимости от источника данных и строгое следование принципу «никаких доверенных источников» в контексте безопасности.
