Pergunta

Se Estou avaliando uma string Python usando eval (), e ter uma classe como:

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

Quais são os riscos de segurança se eu não confiar na corda? Em particular:

  1. É eval(string, {"f": Foo()}, {}) inseguro? Ou seja, você pode alcançar OS ou sys ou algo inseguro de uma instância Foo?
  2. É eval(string, {}, {}) inseguro? Ou seja, eu posso alcançar OS ou sys inteiramente de builtins como len e lista?
  3. Existe uma maneira de fazer builtins não presentes em tudo no contexto eval?

Existem algumas cordas inseguras como "[0] * 100000000" Eu não preocupam, porque na pior das hipóteses eles lento / parar o programa. Estou preocupado principalmente sobre a proteção de dados de usuário externo para o programa.

Obviamente, eval(string) sem dicionários personalizados não é seguro na maioria dos casos.

Foi útil?

Solução

Você não pode proteger eval com uma abordagem de lista negra como esta. Consulte Eval é realmente perigoso para exemplos de entrada que vai segfault o interpretador CPython, dar acesso a qualquer classe que você gosta, e assim por diante.

Outras dicas

eval() permitirá que dados maliciosos para comprometer todo o sistema, matar seu gato, comer o seu cão e fazer amor com sua esposa.

Houve recentemente uma discussão sobre como fazer esse tipo de coisa com segurança na lista python-dev, e as conclusões foram:

  • É realmente difícil fazer isso corretamente.
  • Ela exige patches para o interpretador Python para bloquear muitas classes de ataques.
  • Não faça isso a menos que você realmente quer.

Iniciar aqui para ler sobre o desafio: http: // tav.espians.com/a-challenge-to-break-python-security.html

Em que situação você quer usar eval () in? Você está querendo um usuário para ser capaz de executar arbitrárias expressões? Ou você está querendo para transferir dados de alguma forma? Talvez seja possível para bloquear a entrada de alguma forma.

Você pode começar a os usando builtin funções:. __import__('os')

Para python 2.6+, o ast módulo pode ajudar; em particular ast.literal_eval, embora isso depende exatamente o que você quer eval.

Note-se que mesmo se você passar dicionários vazios para eval (), ainda é possível segfault (C) Python com alguns truques de sintaxe. Por exemplo, tente isso em seu intérprete: eval("()"*8**5)

Você é provavelmente melhor fora transformar a questão em torno de:

  1. Que tipo de expressões você está querendo eval?
  2. Você pode segurar que apenas cordas correspondentes alguma sintaxe estritamente definidos são eval () d?
  3. Em seguida, considere se que é seguro.

Por exemplo, se você está querendo permitir que o usuário digite uma expressão algébrica para avaliação, considerar limitar-los para nomes de uma letra variáveis, números e um conjunto específico de operadores e funções. Fazer cordas não eval () contendo qualquer outra coisa.

Há um muito bom no un-segurança do eval() em de Mark Pilgrim em Python tutorial.

Citado a partir deste artigo:

No final, é possível com segurança avaliar expressões Python não confiáveis, por alguma definição de “seguro” que acaba por não ser muito útil em Vida real. É bom se você está apenas brincar, e é bom se você sempre apenas passá-lo confiança de entrada. Mas qualquer outra coisa é apenas a pedir problemas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top