Имя таблицы параметров в .NET / SQL? - PullRequest
9 голосов
/ 16 декабря 2008

Как следует из темы, я хочу иметь возможность передавать имена таблиц в качестве параметров, используя .NET (не имеет значения, какой язык на самом деле) и SQL Server.

Я знаю, как это сделать для значений, например, command.Parameters.AddWithValue("whatever", whatever) с использованием @whatever в запросе для обозначения параметра. Дело в том, что я хочу сделать это с другими частями запроса, такими как имена столбцов и таблиц.

Это не идеальная ситуация, но я должен ее использовать, на самом деле она не склонна к внедрению SQL-кода, поскольку только кто-то, использующий код, может устанавливать эти имена таблиц, а не конечный пользователь. Однако это грязно.

Итак, возможно ли то, что я спрашиваю?

РЕДАКТИРОВАТЬ: Чтобы прояснить смысл внедрения SQL, имена таблиц передаются только исходным кодом, в зависимости от ситуации. Это разработчик, который определяет это. В любом случае, у разработчика будет доступ к уровню базы данных, поэтому я спрашиваю не столько о безопасности, сколько о том, чтобы сделать код чище.

Ответы [ 7 ]

5 голосов
/ 16 декабря 2008

Вы не можете напрямую параметризовать имя таблицы. Вы можете сделать это косвенно через sp_ExecuteSQL, но вы также можете построить (параметризованный) TSQL в C # (объединить имя таблицы, но не другие значения) и отправить его в виде команды. Вы получаете ту же модель безопасности (т.е. вам нужен явный SELECT и т. Д., И предполагается, что он не подписан и т. Д.).

Также - обязательно внесите в белый список имя таблицы.

4 голосов
/ 16 декабря 2008

Вы можете передать имя таблицы в качестве параметра, как и любой другой параметр. ключ заключается в том, что вы должны создать динамический SQL-оператор, который вам следует учитывать, если его проще встроить на уровне приложений или в процессах.

create procedure myProc

@tableName nvarchar(50)

as

sp_executesql N'select * from ' + @tablename

к примеру, этот пример кода из памяти, посмотрите на BOL для правильного синтаксиса sp_executesql.

Кроме того, это в высшей степени подвержено внедрению SQL-кода, поскольку вы указали, что это не проблема для вас, но всем, кто его читает, следует очень осторожно воспринимать ввод от пользователя для генерации таких запросов, как этот.

3 голосов
/ 16 декабря 2008

Я не думаю Я когда-либо видел эту возможность на любом диалекте SQL, который видел, но это не область знаний.

Я бы предложил ограничить символы AZ, az, 0-9, '.', '_' И '' - и затем использовать любой подходящий брекетинг для базы данных (например, [] для SQL Server, я считаю ) обернуть все это. Затем просто поместите его прямо в SQL.

Не совсем понятно, что вы имели в виду, что это не риск внедрения SQL-кода. Вы имеете в виду, что имена будут в исходном коде и только в исходном коде? Если это так, я согласен, что делает вещи лучше. Возможно, вам даже не понадобится делать брекетинг автоматически, , если , вы доверяете своим разработчикам не быть кретинами (умышленно или нет).

3 голосов
/ 16 декабря 2008

Параметры SQL-запроса могут занимать только буквальное значение. Нельзя использовать параметр для имени таблицы, имени столбца, списка значений или другого синтаксиса SQL. Это стандартное поведение SQL для всех типов баз данных.

Единственный способ сделать имя таблицы динамическим - это вставить переменную в ваш запрос SQL перед тем, как подготовить эту строку в качестве оператора.

Кстати, вы обманываете себя, если думаете, что это не риск для SQL-инъекций. Если вы динамически интерполируете имя таблицы в запрос, вам нужно использовать идентификаторы с разделителями вокруг имени таблицы, так же, как вы используете кавычки вокруг строкового литерала, интерполированного из переменной .

2 голосов
/ 16 декабря 2008

Идея, что он не подвержен внедрению SQL, ошибочна. Он может быть меньше подвержен внедрению SQL от конечных пользователей, но он все еще очень подвержен внедрению SQL. Большинство атак на базы данных осуществляются внутри компании, которая подвергается атаке, а не от конечных пользователей.

У сотрудников могут быть недовольства, они могут быть нечестными, они могут быть недовольны, или они могут просто не быть такими яркими и думать, что это нормально, чтобы обходить безопасность, чтобы делать то, что это ОНИ считает, что должно быть сделано в базе данных.

0 голосов
/ 28 февраля 2015

Я бы просто проверил select OBJECT_ID(@tablename) идея состоит в том, чтобы предотвратить инъекцию, вы знаете, это должно быть имя таблицы, это было, если это возвращает число, то я бы выполнил фактический запрос,

0 голосов
/ 11 июля 2013

Пожалуйста, смотрите это сообщение ответ пользователя Vimvq1987: MySqlParameter as TableName

По сути, вы сначала сверяете имя таблицы со схемой, в которой имя таблицы используется параметризованным образом. Тогда, если все в порядке, имя таблицы допустимо.

Перефразированная основная идея:

    SELECT table_name
    FROM information_schema.tables
    WHERE table_schema = 'databasename'
    AND table_name = @table;

    cmd.Parameters.AddWithValue("@table",TableName);

Если с именем таблицы все будет в порядке, продолжайте свой основной запрос ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...