3 回答

TA贡献1828条经验 获得超3个赞
它不太可能引起问题,但在某些情况下也可能不完全安全。它正在使用当前的文化,这可能会带来一些令人讨厌的冲击。这是一个例子:
using System;
using System.Collections.Generic;
using System.Globalization;
class Test
{
static void Main()
{
// Imagine this somewhere entirely different
var badCulture = (CultureInfo) CultureInfo.CurrentCulture.Clone();
badCulture.NumberFormat.NegativeSign = "0 OR 1=1 OR Id=";
CultureInfo.CurrentCulture = badCulture;
// Here's the code that looks innocent
var idPair = new KeyValuePair<int, int>(-5, 10);
string table = "Foo";
string commandText = $"UPDATE {table} SET Id={idPair.Value} WHERE Id={idPair.Key};";
Console.WriteLine(commandText);
}
}
输出:
UPDATE Foo SET Id=10 WHERE Id=0 OR 1=1 OR Id=5;
现在为...Id中的所有行设置为 10Foo
你可以强制使用不变的文化......但老实说,我不确定它是否值得。
我强烈建议对所有值使用参数。我意识到您不能为表名这样做,并且没有好的方法可以解决这个问题,但是对于您可以的值,IMO应该使用参数。
除此之外,如果您尝试在所有您知道它是安全的地方仔细执行此操作,那么可能会给人一种它总是安全的印象,因此粗心的开发人员可能会遵循相同的模式并将其与字符串值一起使用注意安全。
有多种方法可以使用插值字符串文字FormattableString来创建安全的参数化 SQL,但我看到的大多数代码都需要额外的调整,以便您也可以将其用于表名。

TA贡献1806条经验 获得超5个赞
只要有问题的类型不能在生成的 SQL 中变成任何有害的东西,就可以。请记住,一年后很容易得到这样的代码,却没有意识到实际上没有针对 SQL 注入的保护,并且错误地添加了一些可能很危险的东西。也许有人决定将您所有的键更改为字符串。关键是没有任何东西可以帮助您识别潜在问题 - 没有编译器错误,没有运行时错误,一切都会像以前一样正常工作,直到有人滥用这个漏洞。也就是说,虽然您可以依赖 anint
永远不会包含任意string
值的类型系统,但无法保证一年后idPair
仍会如此。KeyValuePair<int, int>
另外,我永远不会说做坏事是绝对不可能的。到目前为止,权衡通常偏向于参数化查询,因此几乎没有理由不使用它们。

TA贡献1789条经验 获得超8个赞
我不确定你的意思是类型系统足够安全。但是你在这里很容易受到 SQL 注入的攻击。
ifidPair.Key的值是'anything' OR 'x'='x'什么?您将idPair.Value在每条记录上更新 ID。
您应该做的是通过参数传递值,请参见此处:https ://docs.microsoft.com/en-us/ef/core/querying/raw-sql
这里的例子:
context.Blogs
.FromSql("EXECUTE dbo.GetMostPopularBlogsForUser {0}", user)
.ToList();
- 3 回答
- 0 关注
- 528 浏览
添加回答
举报