Какой класс в .NET помогает предотвратить SQL-инъекции
Что проверяют
Знаете ли вы параметризованные запросы и понимаете ли, почему они защищают: текст команды и значения уходят на сервер раздельно. Следом обычно спрашивают, как быть с именем колонки в ORDER BY и безопасен ли FromSqlRaw в EF Core.
Как отвечать
Ответ: SqlParameter для SQL Server, а в общем виде DbParameter, от которого наследуются параметры всех провайдеров, например NpgsqlParameter. Параметры добавляются в SqlCommand.Parameters, в тексте запроса стоят плейсхолдеры @name. Сервер получает шаблон отдельно от значений, значение никогда не разбирается как SQL, а план запроса ещё и переиспользуется.
Что сказать о современном стеке:
- пакет:
System.Data.SqlClientустарел, для нового кода берутMicrosoft.Data.SqlClient; - тип параметра: вместо
AddWithValueлучшеParameters.Add("@email", SqlDbType.NVarChar, 256).Value = email.AddWithValueугадывает тип по значению: строка станетnvarcharс длиной по конкретному значению, отсюда неявные преобразования мимо индекса поvarcharи лишние планы в кеше; - Dapper: анонимный объект в
QueryAsync(sql, new { email })превращается в параметры; - EF Core: LINQ параметризуется сам.
FromSqlиFromSqlInterpolatedпринимают интерполированную строку какFormattableStringи превращают каждое{x}в параметр.FromSqlRawс конкатенацией пользовательского ввода уязвим так же, как голый ADO.NET; - идентификаторы: параметром нельзя подставить имя таблицы, колонки или
ASC/DESC. Такие вещи выбирают из белого списка в коде.
Параметры не отменяют принцип минимальных прав: у учётки приложения не должно быть прав на DROP.
Где спотыкаются
Называют защитой экранирование кавычек через Replace("'", "''"). Это ломается на числовых полях и LIKE, а параметр решает задачу целиком.
Считают хранимую процедуру безопасной самой по себе. Если внутри неё собирается строка и выполняется через EXEC(@sql), инъекция просто переезжает в базу. Нужен sp_executesql с параметрами.
Передают в FromSqlRaw строку, собранную через $"...". Интерполяция случилась ещё до вызова, EF получает готовый текст, и защиты нет.