Ich habe eine Situation mit Code, in der eval()
eine mögliche Lösung gefunden wurde. Jetzt musste ich noch nie etwas verwenden, eval()
aber ich habe viele Informationen über die potenzielle Gefahr gefunden, die es verursachen kann. Trotzdem bin ich sehr vorsichtig, wenn ich es benutze.
Meine Situation ist, dass ich Eingaben von einem Benutzer habe:
datamap = raw_input('Provide some data here: ')
Wo datamap
muss ein Wörterbuch sein. Ich suchte herum und fand heraus, dass eval()
das klappen könnte. Ich dachte, ich könnte möglicherweise die Art der Eingabe überprüfen, bevor ich versuche, die Daten zu verwenden, und das wäre eine praktikable Sicherheitsmaßnahme.
datamap = eval(raw_input('Provide some data here: ')
if not isinstance(datamap, dict):
return
Ich habe die Dokumente gelesen und bin mir immer noch nicht sicher, ob dies sicher ist oder nicht. Wertet eval die Daten aus, sobald sie eingegeben wurden oder nachdem die datamap
Variable aufgerufen wurde?
Ist das ast
Modul .literal_eval()
die einzig sichere Option?
quelle
ast.literal_eval("1 & 1")
wird einen Fehler auslösen, abereval("1 & 1")
nicht.ast.literal_eval
könnten einfach nicht für so etwas verwenden (z. B. könnten Sie einen Parser manuell implementieren).ast.literal_eval()
betrachtet nur eine kleine Teilmenge der Python-Syntax als gültig:Wenn Sie
__import__('os').system('rm -rf /a-path-you-really-care-about')
in übergeben,ast.literal_eval()
wird ein Fehlereval()
ausgelöst, Ihr Laufwerk wird jedoch gerne gelöscht.Da es so aussieht, als würden Sie den Benutzer nur ein einfaches Wörterbuch eingeben lassen, verwenden Sie
ast.literal_eval()
. Es macht sicher, was Sie wollen und nichts mehr.quelle
eval: Dies ist sehr mächtig, aber auch sehr gefährlich, wenn Sie Zeichenfolgen akzeptieren, die aus nicht vertrauenswürdigen Eingaben ausgewertet werden sollen. Angenommen, die zu bewertende Zeichenfolge lautet "os.system ('rm -rf /')"? Es werden wirklich alle Dateien auf Ihrem Computer gelöscht.
ast.literal_eval: Bewerten Sie sicher einen Ausdrucksknoten oder eine Zeichenfolge, die ein Python-Literal oder eine Containeranzeige enthält. Die bereitgestellte Zeichenfolge oder der bereitgestellte Knoten darf nur aus den folgenden Python-Literalstrukturen bestehen: Zeichenfolgen, Bytes, Zahlen, Tupel, Listen, Diktate, Mengen, Boolesche Werte, Keine, Bytes und Mengen.
Syntax:
Beispiel:
Im obigen Code
().__class__.__bases__[0]
nichts als Objekt selbst. Jetzt haben wir alle Unterklassen instanziiert . Hier besteht unserenter code here
Hauptziel darin, eine Klasse mit dem Namen n daraus zu finden.Wir müssen Einwände erheben
code
undfunction
Einwände gegen instanziierte Unterklassen erheben. Dies ist eine alternative Möglichkeit,CPython
um auf Unterklassen von Objekten zuzugreifen und das System anzuhängen.Ab Python 3.7 ist ast.literal_eval () jetzt strenger. Das Addieren und Subtrahieren beliebiger Zahlen ist nicht mehr zulässig. Verknüpfung
quelle
ast.literal_eval("1+1")
funktioniert nicht in Python 3.7 und wie bereits erwähnt, sollte literal_eval auf Literale dieser wenigen Datenstrukturen beschränkt sein. Es sollte nicht in der Lage sein, eine binäre Operation zu analysieren.KABOOM
bitte Ihren Code erklären ? Fand es hier:KABOOM
KABOOM
wird hier schön erklärt: nedbatchelder.com/blog/201206/eval_really_is_dangerous.htmlPython ist eifrig bei der Auswertung und
eval(raw_input(...))
bewertet daher die Benutzereingaben, sobald sie auf die treffeneval
, unabhängig davon, was Sie anschließend mit den Daten tun. Daher ist dies nicht sicher , insbesondere wenn Sieeval
Benutzereingaben vornehmen.Verwenden Sie
ast.literal_eval
.Wenn Sie dies beispielsweise an der Eingabeaufforderung eingeben, ist dies für Sie sehr, sehr schlecht:
quelle
Wenn Sie nur ein vom Benutzer bereitgestelltes Wörterbuch benötigen, ist eine bessere Lösung möglich
json.loads
. Die Hauptbeschränkung besteht darin, dass für json dicts Zeichenfolgenschlüssel erforderlich sind. Sie können auch nur Literaldaten angeben, dies gilt jedoch auch fürliteral_eval
.quelle
Ich war fest mit
ast.literal_eval()
. Ich habe es im IntelliJ IDEA-Debugger versucht und es wurde immer wiederNone
bei der Debugger-Ausgabe zurückgegeben.Aber später, als ich seine Ausgabe einer Variablen zuordnete und sie in Code druckte. Es hat gut funktioniert. Beispiel für das Teilen von Code:
Seine Python-Version 3.6.
quelle