Как защитить от SQL-инъекций с помощью OdbcCommand, когда запрос не параметризован? - PullRequest
1 голос
/ 22 февраля 2012

Я пишу универсальную утилиту sqldump, которая принимает DSN и имя таблицы и выводит содержимое в файл.Это внутреннее приложение, поэтому SQL-инъекция не представляет серьезной угрозы, но я не хочу беспокоиться об этом.Дело в том, что переменная часть запроса на самом деле является именем таблицы, поэтому запрос будет выглядеть так:

select * from [tablename];

... что я не думаю, что будет хорошо работать с параметризованным запросом OdbcCommandслужба поддержки.Я также стараюсь поддерживать все типы DSN как можно более широко, независимо от драйвера на другой стороне DSN.

Существует ли какой-либо универсальный способ дезинфекции моего ввода tablename для защиты от всехSQL-инъекция с использованием объекта OdbcCommand?

Ответы [ 4 ]

2 голосов
/ 22 февраля 2012

Я бы проверил пользовательский ввод по списку таблиц, которые, как вы знаете, там есть, используя код, примерно такой же, как опубликованный здесь , чтобы получить список таблиц (код по ссылке, включенной для потомков):

class Program
{
  static void Main(string[] args)
  {
  string connectionString = GetConnectionString();
  using (SqlConnection connection = new SqlConnection(connectionString))
  {
   // Connect to the database then retrieve the schema information.
   connection.Open();
   DataTable table = connection.GetSchema("Tables");

   // Display the contents of the table.
   DisplayData(table);
   Console.WriteLine("Press any key to continue.");
   Console.ReadKey();
   }
 }

Тем не менее, я согласен с @KeithS выше.Вероятно, это плохая идея.

0 голосов
/ 22 февраля 2012

Единственный специальный символ в указанном в кавычках [] идентификаторе для SQL Server - это ], и его можно экранировать, передав ]]. Так что для этого "select * from [" + tableName.Replace("]", "]]") + "];" должно быть безопасно. Другие системы, однако, могут использовать другие механизмы перехода, так что это не полное решение, если вы хотите подключиться к другому типу базы данных.

В качестве альтернативы рассмотрите каждый символ и посмотрите, является ли он допустимым символом для имен таблиц, которые вы хотите поддерживать. Если вы говорите, что имена таблиц содержат только буквы, цифры и / или пробелы, то внедрение SQL невозможно, потому что вы никогда не сможете заключить в кавычки [quoted table name].

0 голосов
/ 22 февраля 2012

Сначала можно запросить информационную схему, чтобы выяснить, существует ли таблица:

select * 
from information_schema.tables 
where table_schema = @your_database_name and table_name = @table_name

Этот запрос может быть параметризован и НЕ подвержен SQL-инъекциям.

После этого вы можетевведите запрос select * from @table_name.

0 голосов
/ 22 февраля 2012

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

Если вы создаете sql следующим образом

string sql = "SELECT * FROM [" + tablename + "]"; 

и tablename определенокак это

string tablename = "tablename]; DELETE FROM [tablename";

Полученный sql становится

SELECT * FROM [tablename]; DELETE FROM [tablename]; 

Однако это возможно только в том случае, если имя таблицы содержит ].


Примечание.:

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

string sql = "SELECT * FROM tbl WHERE Name = '" + input.Replace("'","''") + "'";
...