【问题标题】:warning EF1000. What the best way to write parameters in "IN" statement?警告 EF1000。在“IN”语句中写入参数的最佳方法是什么?
【发布时间】:2019-02-14 19:27:21
【问题描述】:

EF Core 2.1 引发有关 SQL 注入的警告。有我的代码 sn-p 它发生的地方

var query = await _ctx.Set<TABLE>()
                      .FromSql("Select * from TABLE where Artikelnummer IN (" + string.Join(',', artNum) + ")")
                      .AsNoTracking()
                      .Select(z => new
                      {
                        z.Artikelnummer,
                        z.Property
                      }).ToArrayAsync();

其中artNum(代表Artikel Numbers)是整数数组,如[1,22,34等]。

我无法在FromSql中将artNum作为参数传递,因为会有单引号并且SQL会抛出异常。

我可以将 FromSql 重写为

.Where(x => artNum.Contains(x.Artikelnummer))

但是我的查询比这个更大更复杂,所以 LINQ to Entities 在这种情况下并不好。 应该有那么,问题是如何重写这个查询,这样就不会出现警告?

LINQ to Entities 的执行时间比 LINQ to SQL 长得多,所以这不是解决我的问题的合适方法。

我调查了连接会导致警告,所以应该有没有连接的解决方案。

【问题讨论】:

  • documentaiton 对 SQL 注入非常清楚。我想那里提到的一种方法也应该适用于IEnumerables。
  • 没有办法解决我的问题,因为每次都出现单引号。
  • 您是否尝试过使用类似_ctx.Set&lt;TABLE&gt;().Where(x =&gt; artNum.Contains(x.Artikelnummer)).AsNoTracking()..etc.. 的东西?
  • 警告不是错误。如果您想查看代码以确保实际上不存在 SQL 注入漏洞,则可以取消或忽略该警告。在这里,由于您连接的是 int 列表,而不是 string,因此您可以避免 SQL 注入。

标签: c# sql linq asp.net-core-2.1 ef-core-2.1


【解决方案1】:

我似乎在 EF Core 文档中找不到这样的警告。 (有点)有趣的是,EF Core 2.1 查询翻译器本身并没有参数化生成的 SQL IN 值子句。如果您将查询的.FromSql 行替换为

.Where(x => artNum.Contains(x.Artikelnummer)

顺便说一句,哪个 LINQ to Entities 相当于您的查询,它可以很好地翻译和执行,所以我不知道在这种特殊情况下您为什么要打扰 FromSql

但无论如何,您可以通过在 sql 字符串中包含 {0}{1} 等占位符并通过 params object[] parameters 传递值来参数化 FromSql 查询:

与任何接受 SQL 的 API 一样,参数化任何用户输入以防止 SQL 注入攻击非常重要。您可以在 SQL 查询字符串中包含参数占位符,然后提供参数值作为附加参数。您提供的任何参数值都将自动转换为 DbParameter

你的情况可能是这样的:

var placeholders = string.Join(",", atrNum.Select((v, i) => "{" + i + "}"));
var values = atrNum.Cast<object>().ToArray();

.FromSql("Select * from TABLE where Artikelnummer IN (" + placeholders + ")", values)

【讨论】:

  • FromSql 中的连接导致警告。
  • FromSql方法的第一个参数基本上是字符串,我不知道你在说什么连接,方法实现无法知道字符串是硬编码还是连接几个字符串。您究竟是如何“调查串联导致警告”的?
  • 我尝试使用连接和单个字符串,只有在第二种情况下我才能看到查询中导致的警告。
  • 然后考虑提供minimal reproducible example。使用问题中的当前代码,无论有没有答案中建议的技术,我都没有收到任何警告。顺便说一句,我想我们是在谈论 Visual Studio,而不是像 Resharper 或类似的一些 3rd 方扩展?您是否收到 compile time*runtime 警告?可以发截图吗?如果您使用变量也会发生什么,例如var sql = "Select * from TABLE where Artikelnummer IN (" + placeholders + ")"; 然后.FromSql(sql, values) (或事件您的原始查询与来自变量的连接字符串)?
猜你喜欢
  • 1970-01-01
  • 2011-02-21
  • 2019-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多