Eu tenho uma situação com algum código que eval()
surgiu como uma possível solução. Agora eu nunca tive que usar eval()
antes, mas encontrei muitas informações sobre o perigo potencial que isso pode causar. Dito isto, sou muito cauteloso em usá-lo.
Minha situação é que eu recebo informações de um usuário:
datamap = raw_input('Provide some data here: ')
Onde datamap
precisa ser um dicionário. Eu procurei e descobri que isso eval()
poderia resolver isso. Eu pensei que poderia verificar o tipo de entrada antes de tentar usar os dados e isso seria uma precaução de segurança viável.
datamap = eval(raw_input('Provide some data here: ')
if not isinstance(datamap, dict):
return
Eu li os documentos e ainda não estou claro se isso seria seguro ou não. O eval avalia os dados assim que são inseridos ou depois que a datamap
variável é chamada?
O ast
módulo é .literal_eval()
a única opção segura?
fonte
ast.literal_eval("1 & 1")
irá lançar um erro, maseval("1 & 1")
não irá.ast.literal_eval
algo assim (por exemplo, você poderia implementar um analisador manualmente).ast.literal_eval()
considera apenas um pequeno subconjunto da sintaxe do Python válido:Passar
__import__('os').system('rm -rf /a-path-you-really-care-about')
paraast.literal_eval()
ele gera um erro, maseval()
limpa sua unidade com prazer.Como parece que você está apenas deixando o usuário inserir um dicionário simples, use
ast.literal_eval()
. Ele faz com segurança o que você quer e nada mais.fonte
eval: Isso é muito poderoso, mas também é muito perigoso se você aceitar seqüências de caracteres para avaliar a partir de informações não confiáveis. Suponha que a string que está sendo avaliada seja "os.system ('rm -rf /')"? Ele realmente começará a excluir todos os arquivos do seu computador.
ast.literal_eval: avalie com segurança um nó de expressão ou uma string que contém uma exibição literal de container ou contêiner do Python. A cadeia ou nó fornecido pode consistir apenas nas seguintes estruturas literais do Python: cadeias, bytes, números, tuplas, listas, dictos, conjuntos, booleanos, Nenhum, bytes e conjuntos.
Sintaxe:
Exemplo:
No código acima,
().__class__.__bases__[0]
nada além de objeto em si. Agora que instanciamos todas as subclasses , aqui nossoenter code here
objetivo principal é encontrar uma classe chamada n a partir dela.Precisamos
code
objetar efunction
objetar a partir de subclasses instanciadas. Essa é uma maneira alternativa deCPython
acessar subclasses de objeto e anexar o sistema.A partir do python 3.7, ast.literal_eval () agora é mais rigoroso. A adição e subtração de números arbitrários não são mais permitidas. ligação
fonte
ast.literal_eval("1+1")
não funciona no python 3.7 e, como dito anteriormente, o literal_eval deve ser limitado aos literais dessas poucas estruturas de dados. Não deve ser capaz de analisar uma operação binária.KABOOM
código, por favor? Encontre-o aqui:KABOOM
KABOOM
é bem explicado aqui: nedbatchelder.com/blog/201206/eval_really_is_dangerous.htmlO Python está ansioso em sua avaliação, por
eval(raw_input(...))
isso avaliará a entrada do usuário assim que ela chegareval
, independentemente do que você faz com os dados posteriormente. Portanto, isso não é seguro , especialmente quando vocêeval
insere o usuário.Use
ast.literal_eval
.Como exemplo, digitar isso no prompt será muito, muito ruim para você:
fonte
Se tudo o que você precisa é de um dicionário fornecido pelo usuário, é possível a melhor solução
json.loads
. A principal limitação é que o json dicts requer chaves de string. Além disso, você só pode fornecer dados literais, mas esse também é o casoliteral_eval
.fonte
Eu estava preso
ast.literal_eval()
. Eu estava tentando no depurador IntelliJ IDEA e ele continuava retornandoNone
na saída do depurador.Mas mais tarde, quando atribuí sua saída a uma variável e a imprimi em código. Funcionou bem. Exemplo de código de compartilhamento:
Sua versão python 3.6.
fonte