← Назад к вопросам
Решает ли экранирование проблему 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}"`;
// Недостаточно!
Дополнительные уровни защиты
- Least Privilege — БД пользователь только нужные права
- Входная валидация — проверяй тип и формат данных
- ORM использование — автоматически защищены
- WAF и мониторинг — дополнительная линия защиты
Вывод
Экранирование — пластырь на ране. Правильное решение:
- Всегда используй parameterized queries
- Используй ORM — они защищены по умолчанию
- Никогда не конкатенируй строки в SQL
- Добавляй валидацию входных данных
- Ограничивай права БД пользователя
- Регулярно обновляй зависимости
Это критическое знание для backend разработчика.