← Назад в словарь

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 InjectionXSS
Атака на базу данныхАтака на браузер
Изменяет 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