Сколько было сломано копий при обсуждении вопроса «Возможно ли сделать
eval безопасным?» — невозможно сосчитать. Всегда находится кто-то, кто утверждает, что нашёл способ оградиться от всех возможных последствий выполнения этой функции.
Когда мне понадобилось найти развёрнутый ответ на этот вопрос, я наткнулся на один
пост. Меня приятно удивила глубина исследования, так что я решил, что это стоит перевести.
Коротко о проблеме
В Python есть встроенная функция
eval(), которая выполняет строку с кодом и возвращает результат выполнения:
assert eval("2 + 3 * len('hello')") == 17
Это очень мощная, но в то же время и очень опасная инструкция, особенно если строки, которые вы передаёте в
eval, получены не из доверенного источника. Что будет, если строкой, которую мы решим скормить
eval'у, окажется
os.system('rm -rf /')? Интерпретатор честно запустит процесс удаления всех данных с компьютера, и хорошо ещё, если он будет выполняться от имени наименее привилегированного пользователя (в последующих примерах я буду использовать
clear (
cls, если вы используете Windows) вместо
rm -rf /, чтобы никто из читателей случайно не
выстрелил себе в ногу).