我正在尝试创建一个用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%'
由于您不检查字段值,因此尝试检查字符串参数的值。