Действительно ли «safe_eval» безопасен?
Вопрос
Я ищу «безопасную» функцию оценки для реализации вычислений в виде электронных таблиц (с использованием numpy/scipy).
Функционал для этого ( модуль рексек) был удален из Python начиная с версии 2.3 из-за явно неустранимых проблем безопасности.Есть несколько сторонних хаков, которые призваны сделать это. Самое продуманное решение, которое я нашел, этоэтот рецепт кулинарного бокка Python, "safe_eval".
Нахожусь ли я в достаточной безопасности, если использую это (или что-то подобное) для защиты от вредоносного кода, или мне придется писать собственный парсер?Кто-нибудь знает какие-нибудь лучшие альтернативы?
РЕДАКТИРОВАТЬ:Я только что обнаружил ОграниченныйPython, который является частью Zope.Любые мнения по этому поводу приветствуются.
Решение
Я полагаю, это зависит от вашего определения безопасности.Во многом безопасность зависит от того, что вы передаете и что вам разрешено передавать в контексте.Например, если передан файл, я могу открыть произвольные файлы:
>>> names['f'] = open('foo', 'w+')
>>> safe_eval.safe_eval("baz = type(f)('baz', 'w+')", names)
>>> names['baz']
<open file 'baz', mode 'w+' at 0x413da0>
Кроме того, среда очень ограничена (вы не можете передавать модули), поэтому вы не можете просто передать модуль служебных функций, таких как re или случайный.
С другой стороны, вам не нужно писать свой собственный парсер, вы можете просто написать свой собственный оценщик для Python ast:
>>> import compiler
>>> ast = compiler.parse("print 'Hello world!'")
Надеемся, что таким образом вы сможете реализовать безопасный импорт.Другая идея — использовать Jython или IronPython и воспользоваться возможностями изолированной программной среды Java/.Net.
Другие советы
Написание собственного парсера может быть интересным!Возможно, это лучший вариант, поскольку люди ожидают использовать знакомый синтаксис электронных таблиц (Excel и т. д.), а не Python при вводе формул.Я не знаком с Safe_eval, но предполагаю, что что-то подобное определенно может быть использовано в целях эксплуатации.
Хотя этот код выглядит вполне безопасным, я всегда придерживался мнения, что любой достаточно мотивированный человек может взломать его, если у него будет достаточно времени.Я действительно думаю, что потребуется немало решимости, чтобы пройти через это, но я относительно уверен, что это возможно.
Если вам просто нужно записать и прочитать некоторую структуру данных на Python и вам не нужны реальные возможности выполнения пользовательского кода, этот вариант подойдет лучше:http://code.activestate.com/recipes/364469-safe-eval/
Это гарантирует, что никакой код не выполняется, оцениваются только статические структуры данных:строки, списки, кортежи, словари.
Дэниел,Джинджа реализует среду песочницы, которая может быть вам полезна, а может и нет.Насколько я помню, он еще не «понимает» понимание списков.
Нужные вам функциональные возможности находятся в языковых службах компилятора, см.http://docs.python.org/library/language.htmlЕсли вы определяете свое приложение так, чтобы оно принимало только выражения, вы можете скомпилировать входные данные как выражение и получить исключение, если это не так, например.если есть точки с запятой или формы операторов.