我正在开发一个使用EF Core的项目; 在一个特定情况下,我必须使用原始SQLite命令更新实体的标识.
构建一个SqlCommand并执行它由于某种原因不起作用,以及直接传递参数ExecuteSqlCommand(),它总是抛出异常(我猜这是当前Sqlite驱动程序中的一个错误).
但是,从理论上讲,不应该使用以下代码
string commandText = $"UPDATE {table} SET Id={idPair.Value} WHERE Id={idPair.Key};";
Run Code Online (Sandbox Code Playgroud)
已经阻止了SQL注入,因为这里
table 是我直接从DbContext模型中获得的表名idPair 是一个保证是一个 KeyValuePair<int, int>?
我主要是因为我不知道是否应该禁止这个特定警告,或者尝试以另一种方式执行此操作(无论如何打开关于EntityFrameworkCore.Sqlite的错误报告都在待办事项列表中).
这不太可能导致问题,但在某些情况下,它可能也不完全安全.它正在使用当前的文化,这可能会带来一些令人讨厌的冲击.这是一个例子:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
UPDATE Foo SET Id=10 WHERE Id=0 OR 1=1 OR Id=5;
Run Code Online (Sandbox Code Playgroud)
Id对于Foo...中的所有行,现在设置为10
你可以强制使用不变的文化......但是我不确定它是否值得,说实话.
我强烈建议使用所有值的参数.我意识到你不能为表名这样做,并且没有好办法绕过它,但对于你可以和IMO 应该使用参数的值.
除了其他任何事情,如果你试图在所有你认为安全的地方仔细地做这件事,这会让人觉得它总是安全的,所以一个粗心的开发人员可以遵循相同的模式并使用字符串值,而不是注意安全.
有一些方法可以使用插值字符串文字FormattableString来创建安全的参数化SQL,但是我见过的大多数代码都需要额外的调整才能让你也使用它来表名.
| 归档时间: |
|
| 查看次数: |
356 次 |
| 最近记录: |