Use proper parametrization for your input.
After clarifications in comments, it seems that your parameter is user-input string, this is a wide door opened for injection attacks.
Usually, you can create a SqlCommand
, and provide some SqlParameter
in it.
In EFCore, FromSqlRaw
and FromSqlInterpolated
(in 3.0, replacement for FromSql
in EFCore < 3.0) allow you to shorten this syntax, see the documentation.
string sql = "SELECT * FROM [users].[user] WHERE Id LIKE {0}"
var list = this.context.Person.FromSqlRaw<Person>(sql, "42")
Note that this looks very similar to what you did in the question... But the difference is clearly emphasized in the documentation:
Warning
Always use parameterization for raw SQL queries
When introducing any user-provided values into a raw SQL query, care
must be taken to avoid SQL injection attacks. In addition to
validating that such values don't contain invalid characters, always
use parameterization which sends the values separate from the SQL
text.
In particular, never pass a concatenated or interpolated string ($"")
with non-validated user-provided values into FromSqlRaw or
ExecuteSqlRaw. The FromSqlInterpolated and ExecuteSqlInterpolated
methods allow using string interpolation syntax in a way that protects
against SQL injection attacks.
Indeed, in your case, the string was first interpolated as a string (without any sanity-check), then executed as-is.
FromSqlRaw
had no idea that the "Id" part was coming from a parameter.