Подтвердить что ты не робот

Python: сделать безопасным eval

Я хочу простой способ сделать "API калькулятора" в Python.

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

Я хочу, чтобы он получил строку, скажем "1+1" и вернул строку с результатом, в нашем случае "2".

Есть ли способ сделать eval безопасным для такой вещи?

Для начала я бы сделал

env = {}
env["locals"]   = None
env["globals"]  = None
env["__name__"] = None
env["__file__"] = None
env["__builtins__"] = None

eval(users_str, env)

чтобы вызывающий пользователь не мог испортить мои локальные переменные (или увидеть их).

Но я уверен, что многому занимаюсь здесь.

Являются ли проблемы безопасности eval исправлены или есть слишком много мелких деталей, чтобы заставить его работать правильно?

4b9b3361

Ответ 1

- проблемы безопасности eval, исправляемые или есть слишком много мелких деталей чтобы он работал правильно?

Определенно последнее - умный хакер всегда сможет найти способ защитить ваши меры предосторожности.

Если вас устраивают простые выражения, используя только литералы элементарного типа, используйте ast.literal_eval - для чего это! Для любого любителя я рекомендую пакет синтаксического анализа, например ply, если вы знакомы и комфортно с классическим подходом lexx/yacc или pyparsing для возможного более питонического подхода.

Ответ 2

Можно получить доступ к любому классу, который был определен в этом процессе, и затем вы можете создать его экземпляр и вызвать на нем методы. Можно выполнить sephfault интерпретатор CPython или заставить его выйти. Смотрите: Eval действительно опасен

Ответ 3

Проблемы безопасности не являются (даже близкими к возможностям).

Я бы использовал pyparsing, чтобы разобрать выражение в списке токенов (это не должно быть слишком сложно, потому что грамматика прямо), а затем обрабатывать жетоны индивидуально.

Вы также можете использовать модуль ast для создания АСТ Python (поскольку вы используете действительный синтаксис Python), но это может быть открытыми для тонких дыр в безопасности.

Ответ 4

Perl имеет безопасный модуль eval http://perldoc.perl.org/Safe.html

Googling "эквивалент Python Perl Safe" находит http://docs.python.org/2/library/rexec.html

но этот "ограниченный exec" на Python устарел.

-

В целом безопасность "eval" на любом языке является большой проблемой. Атаки SQL-инъекций - всего лишь пример такой дыры в безопасности. У Perl Safe были ошибки безопасности на протяжении многих лет - последнее, что я помню, это было безопасно, за исключением деструкторов на объектах, возвращенных из безопасного eval.

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

Однако я надеюсь, что когда-нибудь полностью обеспеченные оценки будут доступны на многих/любых языках.