1

Я пытаюсь создать динамическое предложение WHERE с LINQ. У меня есть рабочий пример, но я беспокоюсь, что это не безопасно от 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 строк, как результат, потому что он сравнивает 2 строки. Используя параметры, 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 parse string и создание деревьев выражений. Поэтому, если в strSelectedColumn недействительный столбец, тогда динамический linq вызывает исключение синтаксического анализа перед генерированием SQL-запроса.

при использовании этого

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

вы получите

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

, потому что вы не проверить значение поля, при попытке проверить значение параметров строки.

+1

У вас есть источник или ссылка на то, как LINQ valids является допустимым столбцом? Если они что-то вроде 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"); 
Смежные вопросы