Tengo una situación con algún código que eval()
surgió como una posible solución. Ahora nunca eval()
antes había tenido que usarlo , pero he encontrado mucha información sobre el peligro potencial que puede causar. Dicho esto, soy muy cauteloso acerca de usarlo.
Mi situación es que un usuario me ha dado información:
datamap = raw_input('Provide some data here: ')
Donde datamap
necesita ser un diccionario. Busqué alrededor y descubrí que eso eval()
podría funcionar. Pensé que podría verificar el tipo de entrada antes de intentar usar los datos y eso sería una precaución de seguridad viable.
datamap = eval(raw_input('Provide some data here: ')
if not isinstance(datamap, dict):
return
Leí los documentos y todavía no estoy claro si esto sería seguro o no. ¿Eval evalúa los datos tan pronto como se ingresan o después de datamap
invocar la variable?
¿Es el ast
módulo .literal_eval()
la única opción segura?
fuente
ast.literal_eval("1 & 1")
arrojará un error peroeval("1 & 1")
no lo hará.ast.literal_eval
para algo así (por ejemplo, podría implementar un analizador manual).ast.literal_eval()
solo considera válido un pequeño subconjunto de la sintaxis de Python:Pasando
__import__('os').system('rm -rf /a-path-you-really-care-about')
alast.literal_eval()
generará un error, peroeval()
estará feliz de limpiar la unidad.Como parece que solo está permitiendo que el usuario ingrese un diccionario simple, úselo
ast.literal_eval()
. Hace con seguridad lo que quieres y nada más.fuente
eval: Esto es muy poderoso, pero también es muy peligroso si acepta cadenas para evaluar desde una entrada no confiable. Supongamos que la cadena que se evalúa es "os.system ('rm -rf /')"? Realmente comenzará a eliminar todos los archivos en su computadora.
ast.literal_eval: evalúe de forma segura un nodo de expresión o una cadena que contenga un literal de Python o una pantalla de contenedor. La cadena o nodo proporcionado solo puede consistir en las siguientes estructuras literales de Python: cadenas, bytes, números, tuplas, listas, dictos, conjuntos, booleanos, Ninguno, bytes y conjuntos.
Sintaxis:
Ejemplo:
En el código anterior,
().__class__.__bases__[0]
nada más que el objeto en sí. Ahora instanciamos todas las subclases , aquí nuestroenter code here
objetivo principal es encontrar una clase llamada n a partir de ella.Necesitamos
code
objetar yfunction
objetar desde subclases instanciadas. Esta es una forma alternativa deCPython
acceder a subclases de objetos y adjuntar el sistema.Desde python 3.7 ast.literal_eval () ahora es más estricto. La suma y resta de números arbitrarios ya no están permitidos. enlace
fuente
ast.literal_eval("1+1")
no funciona en python 3.7 y, como se dijo antes, literal_eval debería limitarse a literales de esas pocas estructuras de datos. No debería poder analizar una operación binaria.KABOOM
código, por favor? Lo encontré aquí:KABOOM
KABOOM
se explica muy bien aquí: nedbatchelder.com/blog/201206/eval_really_is_dangerous.htmlPython está ansioso por su evaluación, por
eval(raw_input(...))
lo que evaluará la entrada del usuario tan pronto como llegueeval
, independientemente de lo que haga con los datos después. Por lo tanto, esto no es seguro , especialmente cuando ingresa eleval
usuario.Uso
ast.literal_eval
.Como ejemplo, ingresar esto en el indicador será muy, muy malo para usted:
fuente
Si todo lo que necesita es un diccionario proporcionado por el usuario, es posible una mejor solución
json.loads
. La principal limitación es que json dicts requiere claves de cadena. Además, solo puede proporcionar datos literales, pero ese es también el casoliteral_eval
.fuente
Estaba atrapado con
ast.literal_eval()
. Lo estaba intentando en el depurador IntelliJ IDEA, y seguía volviendoNone
en la salida del depurador.Pero más tarde cuando asigné su salida a una variable y la imprimí en código. Funcionó bien. Ejemplo de código compartido:
Su versión de Python 3.6.
fuente