Pregunta

Si estoy evaluando una cadena de Python usando eval (), y tengo una clase como:

class Foo(object):
    a = 3
    def bar(self, x): return x + a

¿Cuáles son los riesgos de seguridad si no confío en la cadena? En particular:

  1. ¿Es eval(string, {"f": Foo()}, {}) inseguro? Es decir, ¿puede comunicarse con os o sys o algo inseguro de una instancia de Foo?
  2. ¿Es eval(string, {}, {}) inseguro? Es decir, ¿puedo llegar a os o sys por completo desde las construcciones como len y list?
  3. ¿Hay alguna manera de hacer que las construcciones no estén presentes en absoluto en el contexto de evaluación?

Hay algunas cadenas inseguras como " [0] * 100000000 " No me importa porque, en el peor de los casos, ralentizan / detienen el programa. Me preocupa principalmente proteger los datos de los usuarios externos al programa.

Obviamente, eval(string) sin diccionarios personalizados no es seguro en la mayoría de los casos.

¿Fue útil?

Solución

No puede asegurar eval con un enfoque de lista negra como este. Consulte Evaluar realmente es peligroso para ver ejemplos de entradas que harán que el intérprete CPython sea predeterminado, dará acceso a cualquier clase que desee, y así sucesivamente.

Otros consejos

eval() permitirá que los datos maliciosos comprometan todo su sistema, maten a su gato, se coman a su perro y hagan el amor con su esposa.

Recientemente hubo un hilo sobre cómo hacer este tipo de cosas de manera segura en la lista python-dev, y las conclusiones fueron:

  • Es realmente difícil hacer esto correctamente.
  • Requiere parches para el intérprete de Python para bloquear muchas clases de ataques.
  • No lo hagas a menos que realmente quieras.

Comience aquí para leer sobre el desafío: http: // tav.espians.com/a-challenge-to-break-python-security.html

¿En qué situación quieres usar eval ()? ¿Desea que un usuario pueda ejecutar expresiones arbitrarias? ¿O quieres transferir datos de alguna manera? Quizás sea posible bloquear la entrada de alguna manera.

Puede acceder a os utilizando funciones integradas: __import__('os').

Para python 2.6+, el módulo ast puede ayudar; en particular ast.literal_eval, aunque depende exactamente de lo que desea evaluar.

Tenga en cuenta que incluso si pasa diccionarios vacíos a eval (), aún es posible segmentar (C) Python con algunos trucos de sintaxis. Por ejemplo, intente esto en su intérprete: eval("()"*8**5)

Probablemente sea mejor cambiar la pregunta:

  1. ¿Qué tipo de expresiones quieres evaluar?
  2. ¿Puede asegurarse de que solo las cadenas que coinciden con una sintaxis estrechamente definida son eval () d?
  3. Luego considere si ese es seguro.

Por ejemplo, si desea permitir que el usuario ingrese una expresión algebraica para evaluación, considere limitarlos a nombres de variables de una letra, números y un conjunto específico de operadores y funciones. No evalúe las cadenas que contengan nada más.

Hay un muy buen artículo sobre la falta de seguridad de eval() en el Tutorial de inmersión en Python de Mark Pilgrim.

Citado de este artículo:

  

Al final, es posible   evaluar expresiones de Python no confiables,   para alguna definición de & # 8220; seguro & # 8221; ese   resulta no ser terriblemente útil en   vida real. Está & # 8217; está bien si & # 8217; solo estás   jugando, y & # 8217; está bien si   solo pase la entrada de confianza. Pero   cualquier otra cosa es solo pedir   problemas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top