动态LINQ中的安全动态列名称



我正在尝试创建一个用linq的动态。我有一个有效的例子,但我担心它不受SQL注入的安全。

以下LINQ代码:

var oQuery = _db.People.Where("FirstName.Contains(@0)", "kev");

产生以下SQL:

SELECT 
[Extent1].[FirstName] AS [[FirstName], 
[Extent1].[LastName] AS [[LastName], 
WHERE [Extent1].[[FirstName] LIKE '%kev%'

这很好,但是现在我也想使用动态列名称。所以我想我会做以下操作:

var oQuery = _db.People.Where("@0.Contains(@1)", strSelectedColumn,"kev");

,但这会产生以下SQL:

  SELECT 
    [Extent1].[FirstName] AS [[FirstName], 
    [Extent1].[LastName] AS [[LastName], 
    WHERE N'FirstName' LIKE N'%kev%'}

显然是错误的,结果给出了0行,因为他正在比较2个字符串。通过使用参数,linq可能只会在构建查询时将参数注入字符串,而在构建过程中不使用有效的列名。

解决方案是仅使用以下LINQ查询:

var oQuery = _db.People.Where(strSelectedColumn + ".Contains(@0)", "kev");

但是,这会导致可能使用的不安全SQL,可用于注入SQL。

我如何使用我的动态linq列并仍然获得安全的代码?

列名称通常仅包含字母,因此您可以在用户输入上应用" Dumb"消毒:

// user input: "abc';evil statement here"
strSelectedColumn = new string(strSelectedColumn.Where(c => char.IsLetter(c)).ToArray());
// abcevilstatementhere
var oQuery = _db.People.Where(strSelectedColumn + ".Contains(@0)", "kev");

此行

var oQuery = _db.People.Where(strSelectedColumn + ".Contains(@0)", "kev");

生成安全的SQL代码,因为在生成SQL查询动态LINQ Parse String Expression之前并创建表达式树。因此,如果在strSelectedColumn无效列中,则在生成SQL查询之前,Dynamic Linq提出解析异常。

当您使用此

var oQuery = _db.People.Where("@0.Contains(@1)", strSelectedColumn,"kev");

你得到

WHERE N'FirstName' LIKE N'%kev%'

由于您不检查字段值,因此尝试检查字符串参数的值。

最新更新