Имя таблицы параметров в .NET/SQL?

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

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

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

Итак, что я могу спросить?

EDIT: Чтобы понять, что SQL-инъекция очищена, имена таблиц передаются только исходным кодом, в зависимости от ситуации. Это разработчик определяет это. В любом случае разработчик будет иметь доступ к слою базы данных, поэтому причина, о которой я прошу, заключается не столько в безопасности, сколько в том, чтобы сделать код более чистым.

Ответ 1

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

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

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

Ответ 2

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

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

Ответ 3

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

create procedure myProc

@tableName nvarchar(50)

as

sp_executesql N'select * from ' + @tablename

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

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

Ответ 4

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

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

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

Ответ 5

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

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

Ответ 6

Пожалуйста, просмотрите этот ответ пользователем Vimvq1987: MySqlParameter как TableName

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

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

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

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

Если это возвращает ok с именем таблицы, продолжите свой основной запрос...

Ответ 7

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