flawopen.com/SQL Injection/Достаточно ли ORM?
Достаточно ли ORM, чтобы предотвратить SQL-инъекцию?
ORM похожа на кухню, готовящую заказ по бланку: обычный конструктор запросов передаёт значения отдельно. Сырой SQL — другой путь со своими правилами. Проверяйте конкретный API, прежде чем доверять интерполяции.
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.
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 не являются параметрами: выбирайте их из фиксированного списка приложения. Подробности — в руководствах ниже.
Что на самом деле требует «достаточно»
- ✓Используйте конструктор ORM для обычных значений и фильтров.
- ✓В сыром SQL связывайте значения через документированный механизм параметров API.
- ✓Выбирайте динамические идентификаторы из фиксированных списков приложения: параметры не связывают структуру SQL.
- ✓Проверяйте вызовы сырого SQL на конкатенацию, интерполяцию и небезопасные варианты.
FAQ
Нет. Некоторые API сырого SQL связывают отдельно переданные значения, а безопасные API могут принимать интерполированные значения как параметры. EF Core 7+ FromSql принимает FormattableString; FromSqlRaw требует отдельные параметры. Prisma $queryRawUnsafe тоже связывает значения, но не очищает составленный вами SQL-текст. Проверьте контракт метода и не включайте недоверенные значения в структуру SQL.
Источники
- Django SQL-запросы
- SQLAlchemy DBAPI
- Rails Active Record
- EF Core SQL-запросы
- GORM безопасность
- Prisma сырые запросы
- Руководство Django
- Руководство SQLAlchemy
- Руководство Rails
- Руководство EF Core
- Руководство GORM
- Руководство Prisma