1

我試圖用LINQ創建動態WHERE子句。我有一個工作示例,但我擔心SQL注入不安全。動態LINQ中的安全動態列名稱

以下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行作爲結果,因爲他是比較兩個字符串。通過使用參數LINQ可能只是在構建查詢時將字符串作爲字符串注入,而在構建期間不使用有效的列名稱。

的解決方法就是使用下面的LINQ查詢:

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

但這個結果可能不安全的SQL可用於注入SQL。

如何使用我的動態LINQ列,仍然可以獲取安全代碼?

+0

你如何提供用戶可以選擇的字段名稱? –

+0

他們不能真正選擇動態,我用它過濾網格中的列,我想重新使用不同頁面上的網格。 –

回答

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%' 

,因爲你不檢查字段的值,你嘗試檢查字符串參數值。

+1

關於LINQ如何確定它是一個有效的列,你有任何來源或鏈接?如果他們做了像IF這樣的東西存在...與字符串,那麼你仍然可能使用不安全的SQL –

+0

@KevinCloet,你可以在源代碼[DynamicLinq]中看到(http://dynamiclinq.codeplex.com/SourceControl/latest#DynamicLinq/ System.Linq.Dynamic/Dynamic.cs)所有涉及解析 – Grundy

+0

@KevinCloet,簡而言之,當創建表達式樹時嘗試從屬性不存在的類中獲取屬性時引發異常 – Grundy

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");