Ограничения на использование Выполнить и Вычислить на сервере

#std770

Область применения: управляемое приложение, обычное приложение.

1. В общем случае, рекомендуется полностью отказаться от использования произвольного кода (Выполнить / Вычислить). Рекомендация не относится к неизменному внешнему коду, который можно заранее проверить.

Например, расширение может быть проверено администратором перед его добавлением в базу данных, а внешний отчет (или внешняя обработка) может быть проверен пользователем перед интерактивным открытием (через Файл – Открыть). Проверку можно выполнить, как по источнику получения внешнего кода, так и дополнительно по хеш-сумме, если она публикуется.

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

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

При использовании в конфигурации Библиотеки стандартных подсистем, рекомендуется использовать подсистему КонструкторФормул, которая решает эту задачу.

3. При разработке решений следует учитывать, что опасно не только непосредственное выполнение произвольного кода, написанного в режиме 1С:Предприятие, но еще более опасны те места, где методами Выполнить или Вычислить исполняется произвольный код, сконструированный на основе параметров, переданных в серверные функции и процедуры (как из данных, полученных с клиента, так и из базы данных). Ограничения на произвольный код, выполняемый на клиенте, рассмотрены в отдельном стандарте.

Например, код написан следующим образом:

В этом случае не выполняется код, который интерактивно вводит пользователь, но, тем не менее, есть следующая уязвимость:

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

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

4.1. Предварять вызовы Выполнить и Вычислить включением безопасного режима:

УстановитьБезопасныйРежим(Истина);
Выполнить Алгоритм;

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

УстановитьБезопасныйРежим(Истина);

Для каждого ИмяРазделителя Из РазделителиКонфигурации() Цикл
    УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина);
КонецЦикла;

Выполнить Алгоритм;

При использовании в конфигурации Библиотеки стандартных подсистем, следует использовать:

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

4.3. Если выполнение или вычисление произвольного кода используется на сервере для технологических нужд (например, вызов процедуры или функции по полному имени), тогда рекомендуется перейти на прямые вызовы процедур и функций.

В случаях, когда замену сделать невозможно, требуется проверить, что каждая часть имени процедуры или функции (через точку) корректна, а указанные параметры передаются через обращение к переменной с типом Массив. Проверку нужно сделать в той же процедуре или функции непосредственно перед использованием выражений Выполнить / Вычислить.

При использовании в конфигурации Библиотеки стандартных подсистем, следует использовать:

При разработке механизмов встраивания библиотек, рекомендуется использовать имя общего модуля или полное имя менеджера объекта метаданных с фиксированным именем процедуры вместо полного имени обработчика (для которого требуется вызывать процедуры ВыполнитьМетодКонфигурации или ВыполнитьМетодОбъекта).

Правильно:

- описание параметров, заполняемых в процедуре переопределяемого модуля:
//…
// Пример:
//      Проверка = Проверки.Добавить();
//      Проверка.ИмяМодуля  = "МойМодуль";
//…
- вызов прикладной процедуры из библиотеки:
ТекущийМодуль = ОбщегоНазначения.ОбщийМодуль(Проверка.ИмяМодуля);
ТекущийМодуль.ПриПроверкеВеденияУчета(ВыполняемаяПроверка, ПараметрыПроверки);

Неправильно:

- описание параметров, заполняемых в процедуре переопределяемого модуля:
//…
// Пример:
//      Проверка = Проверки.Добавить();
//      Проверка.ОбработчикПроверки  = "МойМодуль.ПроверитьКомментарийВПоступленииТоваров";
//…
- вызов прикладной процедуры из библиотеки:
ОбщегоНазначения.ВыполнитьМетодКонфигурации(Проверка.ОбработчикПроверки, ПараметрыОбработчика);

В общих модулях, модулях менеджеров объектов и модулях объектов, которые содержат процедуры или функции для вызова с помощью ВыполнитьМетодКонфигурации или ВыполнитьМетодОбъекта, требуется добавить следующую экспортную процедуру, в которой перечислить все используемые имена:

// См. СтандартныеПодсистемыСервер.ПриОпределенииМетодовРазрешенныхДляВызоваКакПроизвольныйКод
Процедура ПриОпределенииМетодовРазрешенныхДляВызоваКакПроизвольныйКод(Методы) Экспорт
    Методы.Вставить("УстановкаПараметровСеанса"); // Пример для общего модуля ПользователиСлужебный.
КонецПроцедуры

// См. СтандартныеПодсистемыСервер.ПриОпределенииМетодовРазрешенныхДляВызоваКакПроизвольныйКод
Процедура ПриОпределенииМетодовРазрешенныхДляВызоваКакПроизвольныйКод(Методы) Экспорт
    Если ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.БазоваяФункциональность") Тогда
        Методы.Вставить("ОбновитьДанныеЗависимыеОтПроизводственныхКалендарей");
    КонецЕсли;
КонецПроцедуры

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

Размещение процедуры выполняется без учета требований размещения в разделах программных модулей в стандартах Структура модуля, Обеспечение совместимости библиотек, Разработка конфигураций с повторным использованием общего кода и объектов метаданных. При этом обеспечивается полная обратная совместимость. Для удобства поиска, процедуру рекомендуется размещать в конце модуля в последней области.

Контроль выполняется при вызове ВыполнитьМетодКонфигурации и ВыполнитьМетодОбъекта. Если процедура или функция не предусмотрена для вызова, тогда будет вызвано исключение.

Примечание: в будущих версиях БСП 3.1.13 (если будет) и 3.2.2, если в модуле нет процедуры ПриОпределенииМетодовРазрешенныхДляВызоваКакПроизвольныйКод, тогда разрешен запуск любой процедуры или функции модуля, а с версий БСП 3.1.14 (если будет) и 3.2.3 будет вызвано исключение.

4.4.  Если произвольный код не может быть успешно выполнен в безопасном режиме (например, в нем используется обращение к файлам), то такой код должен быть заменен на внешний код, предварительно пройти аудит и быть размещен в справочнике, к которому есть доступ только у пользователя ответственного за безопасность (например, администратора). Предлагается следующий сценарий работы с внешним кодом:

При использовании в конфигурации Библиотеки стандартных подсистем, для этих целей следует воспользоваться общей формой Расширения (подсистема Базовая функциональность) или подсистемой Дополнительные отчеты и обработки.

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

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

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

Варианты ограничения прав пользователя:

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

б) можно назначить реального пользователя (например, для одноразовых заданий);

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

При использовании в конфигурации Библиотеки стандартных подсистем и наличии подсистемы Регламентные задания БСП для реализации варианта (а) в начале процедуры-обработчика задания разместить вызов процедуры

РегламентныеЗаданияСервер.УстановитьСлужебногоПользователяРегламентногоЗадания

См. также