Определение простыми словами
SQL Injection — это атака, в которой зловредная строка попадает напрямую в SQL-запрос приложения. Если разработчик подставляет пользовательский ввод в текст запроса без экранирования, атакующий может «вырваться» из контекста значения и выполнить произвольную команду базы. Простейший пример: вместо ввода логина admin человек вводит admin' OR '1'='1 — и условие WHERE становится всегда истинным, открывая вход без пароля.
Уязвимость существует с момента появления динамических веб-приложений. По данным OWASP, инъекции остаются в первой тройке угроз с 2003 года. На SQL-инъекциях построены крупнейшие утечки в истории: Sony Pictures (2011), Yahoo (2012), TalkTalk (2015), Equifax (2017). Каждая стоила компаниям сотни миллионов долларов и доверия пользователей.
Атака возможна не только через формы. Любое поле, попадающее в запрос — URL-параметры, заголовки HTTP, cookie, JSON-тело API, имена загружаемых файлов — потенциальная точка входа. Защита строится на двух принципах: использование параметризованных запросов (prepared statements) и валидация ввода. Подробнее в материалах о WAF и PostgreSQL.
Сравнение
| Тип инъекции | Что использует | Сложность | Опасность |
|---|---|---|---|
| Classic (in-band) | прямой вывод результата в ответе | низкая | критическая |
| Error-based | сообщения об ошибках БД | низкая | высокая |
| Union-based | UNION SELECT для слияния таблиц | средняя | высокая |
| Blind boolean | разный ответ при истине и лжи | средняя | высокая |
| Blind time-based | задержка через SLEEP() | высокая | средняя |
| Out-of-band | DNS или HTTP-запросы наружу | высокая | высокая |
| Second-order | сохранение данных и инъекция при последующем чтении | высокая | критическая |
Кейсы использования
Реальные сценарии эксплуатации:
- Обход формы логина:
' OR 1=1 --в поле пароля даёт доступ под первым пользователем из таблицы. - Извлечение базы клиентов: UNION SELECT username, password FROM users — выгрузка хешей паролей.
- Запись произвольного файла: SELECT … INTO OUTFILE ‘/var/www/shell.php’ — установка веб-шелла.
- RCE через xp_cmdshell в MS SQL или COPY … FROM PROGRAM в PostgreSQL.
- Изменение прайс-листа в e-commerce: UPDATE products SET price=1 WHERE id=…
Где SQLi находят чаще всего:
- Самописные CMS на PHP без ORM — 80% уязвимых проектов.
- Старые плагины WordPress, особенно nulled-сборки.
- Поисковые формы с прямой подстановкой запроса в LIKE.
- Фильтры каталога: ?category=2&sort=price — sort часто без проверки.
- API-эндпоинты с подстановкой ID без проверки типа.
Технические детали
Защита и тестирование:
# Уязвимый PHP-код (НЕ ДЕЛАТЬ ТАК)
# $sql = "SELECT * FROM users WHERE login = '" . $_POST['login'] . "'";
# Безопасный код через PDO с prepared statement
# $stmt = $pdo->prepare("SELECT * FROM users WHERE login = :login");
# $stmt->execute(['login' => $_POST['login']]);
# Безопасный код через mysqli
# $stmt = $mysqli->prepare("SELECT * FROM users WHERE login = ?");
# $stmt->bind_param('s', $_POST['login']);
# Тестирование на инъекции через sqlmap (для своего сайта)
sqlmap -u "https://site.ru/page.php?id=1" --batch --risk=3 --level=5
# Поиск в логах Nginx подозрительных запросов
grep -E "(UNION|SELECT.*FROM|--|0x[0-9a-f]+)" /var/log/nginx/access.log
# Включение query log в MySQL для аудита
# SET GLOBAL general_log = 'ON';
# SET GLOBAL general_log_file = '/var/log/mysql/queries.log';
# Жёсткие права пользователя БД для приложения
# GRANT SELECT, INSERT, UPDATE ON site.* TO 'app'@'localhost';
# REVOKE FILE, CREATE, DROP ON *.* FROM 'app'@'localhost';
Дополнительно поможет защита с WAF: сигнатурный анализ блокирует типовые попытки инъекций ещё до попадания в приложение.
🔥 Где это применяется
Частые вопросы
Защищают ли prepared statements от любой SQLi?
Да, если параметры подставляются через placeholder, а не конкатенируются в текст запроса. Уязвимость возможна только в DDL-запросах с динамическими именами таблиц или столбцов.
Помогает ли WAF от SQLi?
WAF блокирует типовые сигнатуры и сканеры, но не заменяет правильный код. Опытный атакующий обходит фильтры обфускацией. WAF — дополнительный слой, не основной.
Что такое второпорядковая SQLi?
Атакующий сохраняет вредоносную строку в БД через безопасный запрос, а инъекция срабатывает позже, когда приложение читает эти данные и подставляет в другой запрос без экранирования.
Можно ли проверить сайт на SQLi?
Да, утилитой sqlmap или сканерами Burp Suite, OWASP ZAP. Тестировать только свои сайты или с письменным разрешением — иначе это уголовное преступление по ст. 272 УК РФ.