Что такое SQL-инъекция и как от неё защититься?

«Что такое SQL-инъекция и как от неё защититься?» — вопрос из категории Тестирование безопасности, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

SQL-инъекция (SQL Injection) — это критическая уязвимость веб-безопасности, возникающая, когда злоумышленник может внедрить произвольный SQL-код в запросы приложения к базе данных. Причина — некорректная обработка или отсутствие валидации пользовательского ввода.

Пример уязвимого кода (PHP):

// Пользовательский ввод напрямую подставляется в запрос
$username = $_POST['username']; // Например: `admin' --`
$password = $_POST['password'];
$sql = "SELECT * FROM users WHERE username='$username' AND password='$password'";
// Итоговый запрос: SELECT * FROM users WHERE username='admin' --' AND password='...'
// Комментарий `--` отменяет проверку пароля, позволяя войти как admin.

Более опасный пример — удаление данных:

Ввод: `'; DROP TABLE users; --`
Запрос: SELECT * FROM users WHERE username=''; DROP TABLE users; --' ...

Методы защиты:

  1. Использование подготовленных выражений (Prepared Statements) с параметризованными запросами — самый эффективный способ.
    // Java (JDBC) пример
    String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
    PreparedStatement stmt = connection.prepareStatement(sql);
    stmt.setString(1, username); // Данные безопасно "привязываются"
    stmt.setString(2, password);
    ResultSet rs = stmt.executeQuery(); // Внедрение невозможно
  2. Использование ORM (Hibernate, Entity Framework) — они генерируют параметризованные запросы.
  3. Экранирование специальных символов (менее надежно, чем prepared statements).
  4. Принцип минимальных привилегий: Учётная запись БД для приложения должна иметь только необходимые права (никакого DROP, DELETE без необходимости).
  5. Валидация и санитизация ввода: Проверка данных по белому списку допустимых символов.

Для тестировщика (QA): Проверка на SQLi входит в пентест. Используются инструменты вроде sqlmap или ручная подстановка payloads (', ' OR '1'='1, '; SLEEP(5)--) в поля форм и параметры URL.