如何在这个 EF Core 查询中避免 SQL 注入?

3

由于EF Core目前不能在数据库中执行“group by”查询,因此我使用以下查询来完成此操作(InvoiceQueryDbQuery类型):

long merchantId = 177;
var invTokens = new List<string> {"qasas", "efsac"};
string inClause = string.Join(",", invTokens);

string query = $@"SELECT i.Token, i.Balance, COALESCE(SUM(i.Amount), 0) AS ProcessingAmount
                  FROM inv.Invoices i
                  WHERE i.Token IN ({inClause})
                    AND i.MerchantId = {merchantId} 
                    AND i.Status = {(int)InvoiceStatus.Scheduled}
                  GROUP BY i.Token, i.Balance";

return await dbContext.InvoicesQuery.FromSql(query).ToListAsync();

上述代码运行完美,但我不喜欢它,因为它会提示一个“可能存在 SQL 注入漏洞”的警告。我知道我可以使用 #pragma 来禁止这个警告(这就是我目前正在使用的)。
我尝试了将查询和参数传递给 FromSql 方法,那样做可以工作,但是进入 IN 子句的参数没有正确映射。
尝试使用 $"'{string.Join("', '", invTokens)}'",但它没有起作用。
如果有帮助,将不胜感激。

4
为什么你要在这里使用原始的SQL查询语句呢?这不是一个复杂的查询,你可以使用Linq来完成。 - DavidG
1
你读过 https://learn.microsoft.com/en-us/ef/core/querying/raw-sql 吗?它展示了如何安全地传递参数(有多种不同的方式)。 - mjwills
1
以上代码运行完美。我很惊讶查询成功了,因为您没有引用单个 inClause 值。在运行时,query 的确切值是什么? - mjwills
4
EF Core 支持分组操作,但需要使用 v2.1 或更高版本。 - DavidG
1
@DavidG:你说得对,我一直以为分组支持会在3.0版本中添加。谢谢! - Efrain Bastidas Berrios
显示剩余2条评论
1个回答

1
自从EF Core 2.0版本以来,您可以使用FormattableString来对查询进行字符串插值。
FromSql和ExecuteSqlCommand中的字符串插值
FormattableString类

在EF Core 2.0中,我们为接受原始SQL字符串的两个主要API:FromSql和ExecuteSqlCommand添加了针对插值字符串的特殊支持。这种新的支持允许以“安全”的方式使用C#字符串插值。

以下是文档中的示例:

var city = "London";
var contactTitle = "Sales Representative";

using (var context = CreateContext())
{
    context.Set<Customer>()
        .FromSql($@"
            SELECT *
            FROM ""Customers""
            WHERE ""City"" = {city} AND
                ""ContactTitle"" = {contactTitle}")
            .ToArray();
 }

这将会产生:
@p0='London' (Size = 4000)
@p1='Sales Representative' (Size = 4000)

SELECT *
FROM ""Customers""
WHERE ""City"" = @p0
    AND ""ContactTitle"" = @p1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接