我遇到一个问题,我需要使用 Entity Framework 核心执行原始查询,该核心需要一个字符串列表作为Where IN 语句的参数,并且我可以让查询正常工作,但我担心 SQL 注入(inject)攻击。我的查询将如下所示:
public static string BulkGetColumn3Query
{
get
{
return @"
SELECT Column1, Column2
FROM TABLE
WHERE column3 IN ({0})";
}
}
现在调用它的方法看起来像这样:
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();
}
我可以做什么来尝试减轻 SQL 注入(inject)攻击?
最佳答案
这绝对是 SQL 注入(inject)问题,因为 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();
}
假设您的列表包含三项:["first", "second", "third"]
。那么你的查询字符串将如下所示:
SELECT Column1, Column2
FROM TABLE
WHERE column3 IN (@p0, @p1, @p2)
参数列表将如下所示:
[ new SqlParameter("@p0", "first")
, new SqlParameter("@p1", "second")
, new SqlParameter("@p2", "third")]
由于所有值都作为参数发送,因此查询现在是安全的。
关于c# - 来自 List<String> 的 FromSqlRaw 参数可以安全地避免 SQL 注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59756675/