Безопасны Мои LINQ Запросы в EF?
Задумывались ли вы когда-нибудь о том, подвержены ли ваши LINQ-запросы в EF атакам с использованием SQL-инъекции? Т.к. вы либо используете данные прямо из текстового поля, либо вставляете всё, что вернул API в базу?
Ну, во-первых, нужно всегда проверять и экранировать вводимые данные. Но, допустим, вы этого не сделали, и …?
Хорошая новость: Entity Framework экранирует ввод. Поэтому, если у вас есть что-то вроде этого:
var userInput = "Jon \"OR 1 = 1";
var evil = await myContext
.People
.Where(p => p.Name === userInput)
.ToListAsync();
Результирующий SQL будет вроде следующего:
SELECT "p"."Id", "p"."Name"
FROM "People" as "p"
WHERE "p"."Name" = 'Jon "OR 1 = 1'
И это хорошо, потому что атака SQL-инъекцией не пройдёт, т.к.
OR 1 = 1 будет рассматриваться как строка, а не как команда SQL.Это не сработает, если вы используете чистые SQL-запросы. Поэтому, такой код:
var userInput = "Jon \"OR 1 = 1";
var evil = await myContext
.People
.FromSqlRaw(
$"SELECT * FROM People WHERE Name = '{userInput}'")
.ToListAsync();
может быть подвержен атакам SQL-инъекцией.
FromSql (до EF Core 7 - FromSqlInterpolated)
FromSql – это более безопасный способ использовать чистый SQL. Метод – часть пакета Microsoft.EntityFrameworkCore.Relational. Вот разница коротко:
var evil = await myContext.
.People
.FromSqlRaw(
$"SELECT * FROM People WHERE Name = {userInput}")
.ToListAsync();
// или
var notSoEvil = await myContext.
.People
.FromSql(
$"SELECT * FROM People WHERE Name = {userInput}")
.ToListAsync();
Хотя они выглядят одинаково, важна сигнатура методов:
FromSqlRaw принимает string, а FromSql — FormattableString. FormattableString представляет собой строку с заполнителями для параметров. Так EF знает, что такое userInput, и сможет правильно его экранировать.Если вы хотите выполнить произвольный SQL-запрос, вы можете использовать
ExecuteSql на объекте Database (вместо DbSet<TYourEntity>).Итого
Используйте
FromSql (или FromSqlInterpolated). В некоторых редких случаях могут быть проблемы форматирования интерполированных строк, но они редки. Если вы столкнётесь с ними, можете использовать FromSqlRaw, но вы должны осознавать риски.Источник: https://steven-giesel.com/blogPost/35ec8819-220a-42bc-9224-a812ec358434/are-my-ef-linq-to-sql-queries-safe