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

#std801

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

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

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

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

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

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

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

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

Правильно:

Если ЭтоПереходНазад Тогда
    Результат = РезультатПриПереходеНазад(Параметры);
ИначеЕсли ЭтоПереходВперед Тогда
    Результат = РезультатПриПереходеВперед(Параметры);
КонецЕсли;

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

Если ЭтоПереходНазад Тогда
    ИмяФункции = "РезультатПриПереходеНазад";
ИначеЕсли ЭтоПереходВперед Тогда
    ИмяФункции = "РезультатПриПереходеВперед";
КонецЕсли;
Результат = Вычислить(ИмяФункции + "(Параметры)");

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

Правильно:

Если Не ИмяСоответсвуетИмениПеременной(ИмяФункции) Тогда
    ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
        НСтр("ru = 'Некорректное имя функции ""%1"".'"), ИмяПроцедуры);
    ВызватьИсключение(ТекстОшибки, КатегорияОшибки.ОшибкаКонфигурации);
КонецЕсли;
Результат = Вычислить(ИмяФункции + "(Параметры)");

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

Результат = Вычислить(ИмяФункции + "(Параметры)");

См. также