我尝试使用LINQ创建动态WHERE子句。我有一个有效的例子,但我担心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%'}
这显然是错误的并且因为他正在比较2个字符串而得到0行。通过使用参数,LINQ可能只是在构建查询时将params作为字符串注入,而不是在构建期间使用有效的列名。
解决方案是使用以下LINQ查询:
var oQuery = _db.People.Where(strSelectedColumn + ".Contains(@0)", "kev");
但是这会导致可能用于注入SQL的不安全SQL。
如何使用动态LINQ列并仍获得安全代码?
答案 0 :(得分:1)
列名通常只包含字母,因此您可以对用户输入应用“哑”清理:
// 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");
答案 1 :(得分:0)
这一行
var oQuery = _db.People.Where(strSelectedColumn + ".Contains(@0)", "kev");
生成安全的SQL代码,因为在生成SQL查询之前动态linq解析字符串表达式并创建表达式树。因此,如果在strSelectedColumn
无效列中,则动态linq会在生成sql查询之前引发解析异常。
当你使用这个
时var oQuery = _db.People.Where("@0.Contains(@1)", strSelectedColumn,"kev");
你得到了
WHERE N'FirstName' LIKE N'%kev%'
因为您没有检查字段的值,所以请尝试检查字符串参数的值。