FlawOpen

flawopen.com/SQL Injection/Достаточно ли ORM?

Достаточно ли ORM, чтобы предотвратить SQL-инъекцию?

Справочная страница
Краткий ответ

ORM похожа на кухню, готовящую заказ по бланку: обычный конструктор запросов передаёт значения отдельно. Сырой SQL — другой путь со своими правилами. Проверяйте конкретный API, прежде чем доверять интерполяции.

НЕБЕЗОПАСНО — пользовательский текст в SQL FromSqlRaw
var sql = $"SELECT * FROM dbo.Blogs WHERE Url = '{url}'";
var rows = await context.Blogs
    .FromSqlRaw(sql)
    .ToListAsync();
// User text is inserted into SQL before execution.
БЕЗОПАСНО — привязка через FromSql (EF Core 7+)
var rows = await context.Blogs
    .FromSql($"SELECT * FROM dbo.Blogs WHERE Url = {url}")
    .ToListAsync();
// EF Core 7+: interpolation becomes a SQL parameter.

Общий шаблон во всех ORM

Конструкторы запросов ORM и API сырого SQL не образуют единую границу безопасности. Официальная документация описывает безопасную передачу значений в Django raw(sql, params), SQLAlchemy text() с отдельными параметрами, условиях Rails с маркерами, EF Core FromSql (7+) / FromSqlInterpolated, GORM Raw(sql, args...) и Prisma $queryRaw с тегированным шаблоном. API различаются: FromSqlRaw безопасен при отдельной передаче параметров, но небезопасен при вставке пользовательского текста в SQL-строку; $queryRawUnsafe тоже связывает отдельные значения, однако конкатенация недоверенного текста остаётся опасной. Имя метода не доказывает, как обрабатываются значения. Передавайте данные документированным способом. Идентификаторы и структура SQL не являются параметрами: выбирайте их из фиксированного списка приложения. Подробности — в руководствах ниже.

Что на самом деле требует «достаточно»

FAQ

Всегда ли методы сырого SQL небезопасны?

Нет. Некоторые API сырого SQL связывают отдельно переданные значения, а безопасные API могут принимать интерполированные значения как параметры. EF Core 7+ FromSql принимает FormattableString; FromSqlRaw требует отдельные параметры. Prisma $queryRawUnsafe тоже связывает значения, но не очищает составленный вами SQL-текст. Проверьте контракт метода и не включайте недоверенные значения в структуру SQL.

Источники

См. также SQL-инъекции (CWE-89): как они работают и как их предотвратить в любом языке — flawopen.com Защищает ли Knex.js от SQL-инъекций? MyBatis ${} и #{}: защита от SQL Injection MySQLi и PDO: безопасные подготовленные запросы Защищает ли NHibernate от SQL-инъекций? NoSQL-инъекция в MongoDB: безопасные фильтры SQL Injection при числовых ID: риск?