Mar*_*ark 5 c# entity-framework-core
我遇到一个问题,我需要使用实体框架核心执行原始查询,该核心需要一个字符串列表作为Where IN 语句的参数,并且我可以让查询正常工作,但我担心 SQL 注入攻击。我的查询将如下所示:
public static string BulkGetColumn3Query
{
get
{
return @"
SELECT Column1, Column2
FROM TABLE
WHERE column3 IN ({0})";
}
}
Run Code Online (Sandbox Code Playgroud)
我现在调用它的方法看起来像这样:
async Task<List<EntityObject>> GetModelObjectByColumn3(List<string> column3Values)
{
var column3ValuesString = string.Join(",", column3Values);
var query = BulkGetColumn3Query.Replace("{0}", column3ValuesString);
return await DbSetObject
.FromSqlRaw(query)
.AsNoTracking()
.ToListAsync();
}
Run Code Online (Sandbox Code Playgroud)
我可以采取什么措施来尝试减轻 SQL 注入攻击?
这绝对是一个 SQL 注入问题,因为column3ValuesString最终会直接发送到数据库。
将其替换为参数化查询:
string BulkGetColumn3Query(List<string> column3Values) {
var selectList = string.Join(", ", column3Values.Select((_, i) => $"@p{i}"));
return $@"SELECT Column1, Column2
FROM TABLE
WHERE column3 IN ({selectList})";
}
async Task<List<EntityObject>> GetModelObjectByColumn3(List<string> column3Values)
{
var query = BulkGetColumn3Query(column3Values);
var sqlParameters = new List<SqlParameter>();
return await Trailers
.FromSqlRaw(query, column3Values.Select((val, i) => new SqlParameter($"@p{i}", val)))
.AsNoTracking()
.ToListAsync();
}
Run Code Online (Sandbox Code Playgroud)
假设您的列表包含三项:["first", "second", "third"]。那么你的查询字符串将如下所示:
SELECT Column1, Column2
FROM TABLE
WHERE column3 IN (@p0, @p1, @p2)
Run Code Online (Sandbox Code Playgroud)
参数列表将如下所示:
[ new SqlParameter("@p0", "first")
, new SqlParameter("@p1", "second")
, new SqlParameter("@p2", "third")]
Run Code Online (Sandbox Code Playgroud)
由于所有值都作为参数发送,因此查询现在是安全的。