Mit ast und whitelists zu machen python's eval () sicher?

OK. Ich weiß, die Experten haben gesprochen und du solltest niemals pythons eval() auf nicht vertrauenswürdige Daten verwenden. Ich bin nicht schlauer als der Rest der Welt und sollte es nicht einmal versuchen. Aber! Ich gehe jedenfalls.

Mein Grundproblem ist, dass ich schaue, um ein kleines Taschenrechner-Evaluator-Programm zu schreiben, das eine nicht vertrauenswürdige Eingabe mit einer Untermenge von Pythons-Syntax einnimmt. Ich weiß: Verwenden Sie Ply oder Pyparsing und schreiben Sie einen Parser und dort gehen wir. Schrauben um mit vorbei an Globalen und Einheimischen zu eval() wird nicht den Trick tun.

Alle Ansätze, die ich gesehen habe (und leery über) versuchen, das Böse aufzuzählen. Hier versuche ich, gut aufzählen – bekomme ein AST, erlaube nur ein paar Knotentypen und überprüfe dann, ob irgendwelche Anrufe zu einer von einer Reihe von Whitelist-Funktionen gehören. Hier ist eine Mini-Implementierung (und ein Gist ):

 import ast import math SAFE_FX = { 'exp': math.exp, } SAFE_NODES = set( (ast.Expression, ast.Num, ast.Call, ast.Name, ast.Load, ast.BinOp, ast.Add, ast.Sub, ast.Mult, ast.Div,) ) class CleansingNodeVisitor(ast.NodeVisitor): def generic_visit(self, node): if type(node) not in SAFE_NODES: raise Exception("%s not in SAFE_NODES" % type(node)) super(CleansingNodeVisitor, self).generic_visit(node) def visit_Call(self, call): if call.func.id not in SAFE_FX: raise Exception("Unknown function: %s" % call.func.id) def my_safe_eval(s): tree = ast.parse(s, mode='eval') cnv = CleansingNodeVisitor() cnv.visit(tree) compiled = compile(tree, s, "eval") return(eval(compiled, SAFE_FX)) 

Also, my_safe_eval('2*(4+exp(1.3))') funktioniert, während my_safe_eval('[].__class__') Tricks und my_safe_eval('open("/something/evil")') ist ebenfalls verboten – Ohne zu verbieten __builtins__ oder __locals__ oder irgendetwas.

Ich … ich denke das funktioniert. Bin ich wütend

2 Solutions collect form web for “Mit ast und whitelists zu machen python's eval () sicher?”

Versuchen Sie asteval , scheint wie die Sache, die Sie brauchen. Ansonsten gibt es diese sichere eval

Zope hat eine Sache namens RestrictedPython , können Sie es überprüfen, zumindest um Ihren Ansatz zu validieren oder möglicherweise wieder verwenden ihren Code. Es ist konfigurierbar und wiederverwendbar.

Hier ist meine andere Antwort auf eine ähnliche Frage.

  • Warum ist python decode ersetzt mehr als die ungültigen Bytes aus einer codierten Zeichenfolge?
  • Wie schütze ich mich vor einer gzip oder bzip2 bombe?
  • Verweigern, einen Teil einer Datei in Python zu lesen
  • Sichere Optionen zum Speichern von Openssl-Passwort auf einem Server (Linux, Python, CherryPy)
  • Wie kann ich mich vor einer Reißverschlussbinde schützen?
  • Throttling Brute-Force-Angriffe in Django
  • Django SECRET_KEY
  • GET STIX Daten vom TAXII Server basierend auf Indikatoren (IP und Hash)
  • Unwaschbarer Typfehler beim Ändern von SqlAlchemy Modellen
  • Welche Sicherheitsfragen müssen bei der Arbeit mit Google App Engine angesprochen werden?
  • Ist mein Code verhindert Verzeichnis Traversal?
  • Python ist die beste Programmiersprache der Welt.