← Назад к вопросам

Решает ли экранирование проблему SQL Injection

1.8 Middle🔥 161 комментариев
#Базы данных и SQL#Безопасность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Экранирование и SQL Injection: полный разбор

Короткий ответ: экранирование помогает, но не решает проблему полностью. Это распространённое заблуждение, которое привело ко многим уязвимостям. Объясню почему.

Почему простого экранирования недостаточно

SQL Injection работает на уровне синтаксиса SQL, а не строк. Экранирование защищает только от строковых атак:

const userName = "admin'--";
const query = `SELECT * FROM users WHERE name = "${escape(userName)}"`;
// Результат: SELECT * FROM users WHERE name = "admin\\'--"
// Кавычка экранирована, но комментарий всё ещё работает

Экранирование решает только часть проблемы:

  • Защищает от простых строковых подстановок
  • Не защищает от логических операторов (OR, AND)
  • Не защищает от комментариев (--, /**/)
  • Не защищает от числовых полей (1 OR 1=1)
  • Не защищает от структурных атак

Правильное решение: Parameterized Queries

Это единственный надёжный способ. SQL структура и данные разделены на уровне драйвера БД:

const mysql = require("mysql2/promise");

const connection = await mysql.createConnection({
  host: "localhost",
  user: "root",
  password: "password",
  database: "mydb"
});

const [rows] = await connection.execute(
  "SELECT * FROM users WHERE id = ? AND email = ?",
  [userId, userEmail]
);

Почему это безопасно:

  • Разделение кода и данных: SQL шаблон компилируется один раз
  • Любые данные — только данные: 1 OR 1=1 будет значением, а не SQL кодом
  • Невозможно изменить SQL структуру: даже если передать опасные последовательности

Примеры с разными инструментами

PostgreSQL с pg:

const pg = require("pg");
const client = new pg.Client();

const result = await client.query(
  "SELECT * FROM users WHERE username = $1 AND role = $2",
  [username, role]
);

TypeORM:

const user = await User.find({
  where: {
    email: userInput,
    role: "admin"
  }
});

Prisma:

const user = await prisma.user.findUnique({
  where: { email: userInput }
});

Опасные паттерны

Строковая конкатенация — НИКОГДА:

const query = `SELECT * FROM users WHERE id = ${id}`;
// Опасно!

Экранирование вручную:

const escaped = input.replace(/'/g, "''");
const query = `SELECT * FROM users WHERE name = "${escaped}"`;
// Недостаточно!

Дополнительные уровни защиты

  1. Least Privilege — БД пользователь только нужные права
  2. Входная валидация — проверяй тип и формат данных
  3. ORM использование — автоматически защищены
  4. WAF и мониторинг — дополнительная линия защиты

Вывод

Экранирование — пластырь на ране. Правильное решение:

  • Всегда используй parameterized queries
  • Используй ORM — они защищены по умолчанию
  • Никогда не конкатенируй строки в SQL
  • Добавляй валидацию входных данных
  • Ограничивай права БД пользователя
  • Регулярно обновляй зависимости

Это критическое знание для backend разработчика.

Решает ли экранирование проблему SQL Injection | PrepBro