В Perl существует два синтаксиса конструкции eval:
Особенности обработки ошибок:
$@ содержится текст ошибки (если ошибка была), иначе $@ пустой.eval BLOCK быстрее, безопаснее и предпочтительнее, когда не требуется выполнять динамический код.eval STRING удобен для динамического создания кода, но дополнительно компилирует строку, что медленнее и потенциально опаснее.# Пример использования eval BLOCK my $result = eval { die "Error!" unless 1 + 1 == 2; return "OK"; }; if ($@) { warn "Error caught: $@"; } # Пример использования eval STRING my $code = '$x = 1 + 2; $x;'; my $res = eval $code; if ($@) { warn "Eval string error: $@"; }
Если внутрь eval STR рассовать динамически подставляемые переменные без должного экранирования, могут ли возникнуть дополнительные риски?
Да, если подставляемая строка формируется из переменных, особенно полученных извне (например, из ввода пользователя), возникает угроза security/injection. Всегда нужно использовать экранирование или не использовать eval STRING для чужих данных.
my $user_code = 'system("rm -rf /");'; eval $user_code; # ОЧЕНЬ ОПАСНО!
История
В аудиторском скрипте для проверки параметров виртуальных машин использовался eval STRING, в который "по ошибке" попадали данные, прочитанные из внешнего файла конфигураций. Однажды файл был подменен, что привело к исполнению кода злоумышленника и компрометации сервера.
История
Разработчик обернул потенциально аварийную часть кода в eval BLOCK, ожидая, что он "захватит" не только runtime-ошибки, но и compile-time (например, синтаксические ошибки). Но синтаксическая ошибка (например, опечатка в имени переменной) не перехватывается eval BLOCK — она вызвала аварийное завершение процесса.
История
При десериализации сложных структур данных через eval STRING после Dumper-дампа, забыли убедиться, что строка содержит только допустимый Perl-код — пользователь с помощью input injection добавил исполняемый код, что привело к выполнению вредоносных команд на сервере.