#c# #sql #sql-server #oracle
#c# #sql #sql-сервер #Oracle
Вопрос:
Итак, у нас есть пользовательский регистратор (действительно хотел использовать Log4Net, просто не будет работать в этом случае). Из файла конфигурации вы можете настроить имя таблицы, в которую будет вставляться.
Я настраиваю оператор insert, но в операторе insert будет использоваться настраиваемое имя таблицы, и это потенциальный вектор для атаки. Вот пример инструкции, которая будет построена:
"insert into " theTableName " (static column list) values(parameterized list of values)"
Итак, мои вставленные значения параметризованы и довольно безопасны, это имя таблицы, которое может содержать неприятности.
Мой вопрос в том, что я могу сделать, чтобы очистить имя таблицы? Я думаю, что характер кода, который злоумышленник будет вводить, должен немного отличаться от обычного. — вместо галочки вы потенциально можете закрыть statment с помощью «table name () values (); сделайте что-нибудь плохое —
(или что-то в этом роде, я полагаю). С этой целью я думал о проверке «;» и «—«.
Кто-нибудь может предложить лучший способ очистки этого? (это будет использоваться с Oracle и SQL server)
Комментарии:
1. Откуда берется имя таблицы? Если это то, что определяете только вы, то это настолько безопасно, насколько вы хотите.
2.
theTableName
Происходит ли значение полностью или частично за пределами кода вашего приложения?3. @Marc B Имя_таблицы может быть указано в app.config, поэтому, если бы оно было установлено на рабочем столе пользователя, им можно было бы манипулировать. (для парней, не являющихся .net, — файл think .ini)
4. затем сравните
theTableName
с предопределенными строками
Ответ №1:
Это все еще не защищает вас от атак ОБЪЕДИНЕНИЯ (и еще нескольких). Лучше всего выполнить проверку белого списка на наличие латинских букв или похожих, если вы знаете, что разрешено.
Другие символы для проверки будут
()`"'
и пробелы.
Ответ №2:
Я думаю, что у вас есть потенциально более серьезная проблема, которая заключается в том, что пользователь может указать синтаксически безопасное и допустимое имя таблицы, которого просто не существует в базе данных.
Поэтому я бы сделал это:
-
Создайте строку ВСТАВКИ (включая имя таблицы) только один раз, при загрузке файла конфигурации.
-
Проверьте имя таблицы в то время, проверив системные метаданные, чтобы убедиться, что это реальная, действительная таблица.
В это время вы можете предупредить пользователя, что ведение журнала отключено, поскольку таблица «theTableName» не существует в базе данных.
Ответ №3:
почему бы не использовать theTableID
числовое значение идентификатора для строки, в которой вы храните имя таблицы theTableName
. Вы можете сохранить это числовое значение ID в файле конфигурации на КОМПЬЮТЕРЕ пользователя и передать его в приложение. Затем вы можете просмотреть его с помощью параметризованного запроса, а затем объединить фактическое имя таблицы строк в запрос. Это будет безопасно.
Ответ №4:
Очевидным решением для меня было бы сначала проверить имя таблицы, которое вы собираетесь использовать в динамическом SQL, используя статический SQL:
select * from sys.tables where name = @thetablename
Поскольку этот запрос связывает переменную, а не объединяет ее, он должен быть невосприимчив к SQL-инъекции. Если запрос возвращает запись, продолжайте, в противном случае обработайте ее как ошибку.
Ответ №5:
Я думаю, главный вопрос заключается в том, почему переменная tablename даже предоставляется пользователю, использующему страницу, для которой ведется журнал.
За исключением этого, проверка белого списка либо по заданному массиву значений, либо по набору, который вы создаете на лету, запрашивая в системном каталоге имена таблиц и сбрасывая их в массив, и все это просто выполняет.Содержит (имя_таблицы) в массиве или любой другой эквивалент для выбранного вами языка, вероятно, самый безопасный способ.