2010-08-18 15 views
30

Quiero una manera fácil de hacer una "API de calculadora" en Python.Python: make eval safe

En este momento no me importa mucho sobre el conjunto exacto de las características de la calculadora va a apoyar.

Quiero que reciba una cadena, digamos "1+1" y devuelva una cadena con el resultado, en nuestro caso "2".

¿Hay una manera de hacer eval seguro para una cosa así?

Para empezar me gustaría hacer

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

eval(users_str, env) 

de modo que la persona que llama no puede meterse con mis variables locales (o ver).

pero estoy seguro de que estoy supervisando mucho aquí.

son eval 's problemas de seguridad que se puede fijar o hay demasiados pequeños detalles para que funcione la derecha?

+0

Consulte también: http://stackoverflow.com/questions/594266/equation-parsing-in-python – kennytm

+0

Es éste puede resolver su problema https://github.com/odoo/odoo/blob/d7cfa8c502f27bee5c2fccb35db47b08e3b3804b/odoo/ tools/safe_eval.py – bkmagnetron

Respuesta

43

son los problemas de seguridad de eval corregible o no son demasiados detalles diminutos para que funcione la derecha?

Definitivamente lo último: un hacker inteligente siempre se las arreglará para encontrar una forma de evitar sus precauciones.

Si está satisfecho con expresiones normal utilizando literales de tipo primaria solamente, usar ast.literal_eval - eso es para lo que sirve! Para cualquier cosa más elegante, recomiendo un paquete de análisis, como ply si está familiarizado y cómodo con el enfoque clásico lexx/yacc, o pyparsing para un enfoque posiblemente más Pythonic.

+0

. Todavía es posible bloquear' ast.literal_eval': / –

2

Las cuestiones de seguridad no son (ni siquiera cerca) que puede fijarse.

Usaría pyparsing para analizar la expresión en una lista de tokens (esto no debería ser demasiado difícil, porque la gramática es directa) y luego manejar los tokens individualmente.

También podría usar el módulo ast para construir un AST de Python (ya que está utilizando la sintaxis de Python válida), pero esto puede estar abierto a sutiles problemas de seguridad.

+0

Creo que esto no funciona, porque configuro locals y globales en None para que no sean visibles desde dentro de la expresión eval. – flybywire

+0

@flybywire: disculpas, eso es cierto; editado Aún así es una mala idea. – katrielalex

+0

@flybywire: http://stackoverflow.com/questions/661084/security-of-pythons-eval-on-untrusted-strings – katrielalex

7

Es posible acceder a cualquier clase que se haya definido en el proceso, y luego puede crear una instancia e invocar métodos en ella. Es posible segfault el intérprete CPython, o hacer que se cierre. Ver esto: Eval really is dangerous

1

Perl tiene un módulo de seguridad eval http://perldoc.perl.org/Safe.html

googlear "equivalente Python Perl de seguridad" encuentra http://docs.python.org/2/library/rexec.html

pero está en desuso este Python "restringido el ejecutivo".

-

general, "eval" seguridad, en cualquier idioma, es un gran problema. Los ataques de inyección SQL son solo un ejemplo de ese agujero de seguridad.Perl Safe ha tenido errores de seguridad a lo largo de los años, el más reciente que recuerdo, era seguro, excepto por los destructores en los objetos devueltos por la evaluación segura.

Es el tipo de cosas que podría usar para mis propias herramientas, pero no expuestas en la web.

Sin embargo, espero que algún día las evaluaciones totalmente seguras estén disponibles en muchos/cualquier idioma.