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 datamapnecesita 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 datamapinvocar la variable?
¿Es el astmó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_evalpara 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 hereobjetivo principal es encontrar una clase llamada n a partir de ella.Necesitamos
codeobjetar yfunctionobjetar desde subclases instanciadas. Esta es una forma alternativa deCPythonacceder 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.KABOOMcódigo, por favor? Lo encontré aquí:KABOOMKABOOMse 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 elevalusuario.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 volviendoNoneen 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