SQL Injection (SQL-инъекция)
SQL Injection (SQL-инъекция) (SQL Injection) — внедрение SQL-кода
Контекст термина
Термин используется в контексте безопасности веб-приложений и работы с базами данных (MySQL, PostgreSQL, MSSQL и др.). Не относится к легитимным SQL-запросам или ORM как таковым.
Суть в одном предложении
SQL Injection — это уязвимость, при которой злоумышленник внедряет произвольный SQL-код в запрос к базе данных.
Краткое определение
SQL Injection — это тип атаки, при которой пользовательский ввод используется для изменения структуры SQL-запроса и выполнения нежелательных операций с базой данных.
Где используется (контекст появления)
- Веб-приложения с ручной сборкой SQL-запросов
- CMS и самописные сайты
- Админ-панели
- Старые PHP-проекты без prepared statements
- Небезопасные REST API
Когда это особенно опасно
- Прямой конкатенации строк в SQL
- Отсутствии валидации входных данных
- Использовании устаревших функций (mysql_query)
- Доступе БД с избыточными правами (root)
Как возникает SQL Injection
Небезопасный код:
$id = $_GET['id']; $query = "SELECT * FROM users WHERE id = $id"; $result = mysqli_query($conn, $query);
Если пользователь передаст:
?id=1 OR 1=1
Запрос превратится в:
SELECT * FROM users WHERE id = 1 OR 1=1;
Результат — возврат всех пользователей.
Более опасный пример
?id=1; DROP TABLE users;
Если база разрешает мультизапросы — таблица будет удалена.
Типы SQL Injection
- Classic SQLi (через форму или URL)
- Blind SQLi (без прямого вывода ошибки)
- Time-based SQLi (через задержки)
- Error-based SQLi
- Union-based SQLi
Как защищаются от SQL Injection
1️⃣ Prepared Statements (главный метод)
PHP (PDO):
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$id]);
MySQLi:
$stmt = $conn->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
2️⃣ ORM
Использование ORM (например, Eloquent, Doctrine) минимизирует риск, если не использовать raw-запросы.
3️⃣ Ограничение прав БД
Нельзя:
- Давать пользователю БД права DROP, ALTER, GRANT
Правильно:
- Отдельный пользователь с минимальными правами
4️⃣ Валидация и фильтрация
- Проверка типов
- Приведение к int
- Белые списки значений
SQL Injection ≠ XSS
| SQL Injection | XSS |
|---|---|
| Атака на базу данных | Атака на браузер |
| Изменяет SQL | Внедряет JS |
| Нарушает целостность данных | Крадёт сессии |
Архитектурное значение
SQL Injection — одна из самых старых и опасных уязвимостей веба.
Она:
- Может привести к утечке данных
- Позволяет изменить базу
- Дает доступ к административным данным
- Может привести к RCE через хранимые процедуры
Где особенно актуально
- WordPress без правильных API
- Самописные PHP-проекты
- Legacy-код
- Старые CMS
Современные фреймворки по умолчанию используют prepared statements.
Частые ошибки
❌ Конкатенация строк ❌ Использование $_GET напрямую ❌ Raw-запросы в ORM ❌ Отсутствие ограничения прав БД
Что не является SQL Injection
- Ошибка в SQL-запросе
- Неправильная логика WHERE
- Медленный запрос
Это именно внедрение чужого кода в SQL.
Аналоги и связанные термины
- XSS
- CSRF
- Prepared Statement
- ORM
- Database Security
Пример использования
«В проекте устранена SQL Injection путём перехода на prepared statements.»
Мини-FAQ
Защищает ли ORM от SQL Injection полностью? Нет, если использовать raw SQL.
Нужно ли экранировать данные вручную? При prepared statements — нет.
SQL Injection всё ещё актуален? Да, особенно в legacy-системах.
Смотри также
- XSS
- CSRF
- Database Security
- Prepared Statement