Как избежать SQL-инъекций при использовании символов '[' и ']' для имен схем / таблиц? - PullRequest
2 голосов
/ 23 октября 2010

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

Поскольку случаи были простыми (схемы и имена таблиц на простом английском языке, без цифр и символов), было легко избежать SQL-инъекций, просто запретив любой символ вне диапазонов A-Z и a-z. Но такой подход неудачен, когда приложение должно обрабатывать любые символы Unicode, когда они могут быть частью имени схемы или таблицы.

Теперь, если SQL-запрос использует '[' и ']' для включения имен в схему, таблицу и столбец, достаточно ли запретить только ']' символов в именах, чтобы избежать SQL-инъекции?

Пример:

A'B - допустимое имя таблицы. Итак:

string tableNameFromUserInput = "A'B"; // Let's imagine it is a user input.
using (SqlCommand getEverything = new SqlCommand(
    string.Format("select * from [dbo].[{0}]", tableNameFromUserInput),
    sqlConnection)
{
    // Do stuff.
}

совершенно корректно, и нет никаких причин блокировать символ одинарной кавычки.

Так есть ли риск внедрения SQL в следующем коде?

string tableName = UserInput.GetUnsafeInputFromUser();

// Search for ']' character only.
if (tableName.IndexOf(']') != -1)
{
    throw new HackerDetectedException();
}
else
{
    using (SqlCommand getEverything = new SqlCommand(
        string.Format("select * from [dbo].[{0}]", tableNameFromUserInput),
        sqlConnection)
    {
        // Do stuff.
    }
}

Изменить:

После некоторого поиска я обнаружил статью о Идентификаторы с разделителями в Microsoft SQL. Согласно этому:

Тело идентификатора может содержать любую комбинацию символов в текущей кодовой странице, кроме самих символов-разделителей.

Кстати, идентификаторы с разделителями ограничены 128 символами.

Чтобы заставить его работать:

  • Символ ']' должен быть запрещен (или, лучше, заменен на ']]'; см. Ответ Марка Байерса ниже).
  • Длина должна быть ограничена 128 символами (не сделано в приведенном выше примере кода),
  • Кодовая страница, вероятно, должна быть проверена, чтобы получить правильную таблицу.

Ответы [ 4 ]

3 голосов
/ 23 октября 2010

Я думаю, это будет безопасно. Такие символы, как обратная косая черта, обрабатываются как буквенные символы, поэтому их следует безопасно включать в имена таблиц. Единственный персонаж, о котором я могу сразу подумать, это проблема ], которую вы уже запретили. Кстати, чтобы включить ] в имя таблицы, ее нужно записать как ]], поэтому вместо полного отказа от нее можно вместо этого сделать tableName.Replace("]", "]]").

Однако, чтобы быть в безопасности, вы должны использовать белый список, как вы предложили. Чтобы сделать это, в то же время допуская использование символов юникода в именах таблиц, вы можете рассмотреть возможность использования регулярного выражения @"^\w+$" для проверки имени таблицы, поскольку это также принимает символы Юникода.

2 голосов
/ 23 октября 2010

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

2 голосов
/ 23 октября 2010

если выбран только sql, т. Е. Вы не собираетесь сохранять какие-либо изменения, вы можете запустить команду sql в транзакции в блоке try и выполнить откат в блоке finally.

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

Этот конкретный старт работает, когда вы извлекаете данные, но не обновляете.

   try
        {
            //Run command in transaction.
        }
        catch (Exception ex)
        {
            // rollback transaction
        }

        finally
        {
            // rollback transaction
        }

, а также это было проверено для базы данных Sybase

0 голосов
/ 23 октября 2010

Я думаю, что следующее может разрушить вашу базу данных, возможно, следующее из OWASP:
'and 1 in (select min(name ) from master.dbo.sysdatabases where name >'.' ) --'

Для тех, кому нужны ресурсы OWASP:
OWASP

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