Seite 1 von 1
eval - nutzbar für sandbox?
Verfasst: Sonntag 14. November 2010, 22:23
von jtk
Hallo
kann man mit folgendem code eine Sandbox für einen Funktionsaufruf bauen?
Code: Alles auswählen
import __builtin__
erlaubt={
# funktionen, die aufgerufen werden dürfen
}
blocker={} # wird mit überschribungen für alle builtin werte gefüllt
for b in dir(__builtin__):
blocker[b]=None # oder irgnedein andere dummy-wert
try:
eval("irgendeine_Funktion('Was auch immer')",blocker,blocker)
except:
.... Fehler Abfangen ...
Ist das sicher, das damit nichts das hauptprogrammmanipuliert?
ich möchte objektstrukturen abspeichern und dies in form von Python Code (dictionarys, listen, Konstruktoren mit schlüsselwortargumenten) tun, um nicht so viel parserei zu haben,
aber möchte nicht, dass eine manipulierte datei irgendetwas ausführen kann
Re: eval - nutzbar für sandbox?
Verfasst: Sonntag 14. November 2010, 22:42
von DasIch
Solange man auf ein Objekt zugreifen kann, kann man sich ueber die mro oder __bases__ zu object durchhangeln und von dort mit __subclasses__ auf so ziemlich alles zugreifen und jede Menge Schaden anrichten.
Re: eval - nutzbar für sandbox?
Verfasst: Sonntag 14. November 2010, 23:12
von lunar
@jtk: "eval()" ist nicht sicher, selbst wenn man den Namensraum strikt kontrolliert. Reichen einfache Literalformen für Deine Zwecke aus, so kannst Du "ast.literal_eval()" nutzen. Andernfalls musst Du den Quelltext mithilfe des "ast"-Moduls parsen und den generierten Syntaxbaum anschließend manuell auswerten, wobei Du nur eine zu definierende, „sichere“ Untermenge an Anweisungen und Ausdrücken zulässt.
Re: eval - nutzbar für sandbox?
Verfasst: Montag 15. November 2010, 10:20
von Hyperion
Vielleicht hilft dir da auch dieer Thread weiter; da gibt es ein Beispiel für das Nutzen von ast:
http://python-forum.de/viewtopic.php?f= ... al+sandbox
Re: eval - nutzbar für sandbox?
Verfasst: Montag 15. November 2010, 13:05
von jtk
Danke, ich werds mir mal anschauen!
Re: eval - nutzbar für sandbox?
Verfasst: Montag 15. November 2010, 13:26
von jtk
in der docu für marshal steht, das dies unsicher sei (
http://docs.python.org/library/marshal. ... le-marshal) - inwiefern?
Re: eval - nutzbar für sandbox?
Verfasst: Montag 15. November 2010, 14:34
von lunar
@jtk: Da die Dokumentation darüber keine genaueren Angaben macht, musst Du die Implementierung dieses Moduls zu Rate ziehen. Ins Blaue geraten vermute ich, dass die Implementierung Eingabedaten nicht auf Gültigkeit prüft und somit bei ungültigen Daten anfällig für Pufferüberläufe oder ähnliches ist.
Re: eval - nutzbar für sandbox?
Verfasst: Montag 15. November 2010, 14:47
von jens
Re: eval - nutzbar für sandbox?
Verfasst: Montag 15. November 2010, 14:51
von Defnull
Marshal kann auch Code-Objekte abbilden und damit beliebigen Python Code enthalten. Darüber hinaus wird es beim Einlesen nur grob auf Fehler überprüft. In der Vergangenheit gab es haufenweise Bugs, die bei kaputtem marschal input zu abstürzen oder undefinierten Verhalten geführt haben. Das gleiche gilt übrigens für Pickle.
Ich würde die Daten entweder kryptographisch signieren, oder ein sichereres Format wählen (json, YAML, XML).
Re: eval - nutzbar für sandbox?
Verfasst: Montag 15. November 2010, 15:11
von lunar
@Defnull: Wo genau ist das Problem darin, dass "marshal" Code-Objekte abbilden kann? Der Code wird schließlich beim Laden nicht ausgeführt.
Re: eval - nutzbar für sandbox?
Verfasst: Montag 15. November 2010, 15:18
von Defnull
lunar hat geschrieben:@Defnull: Wo genau ist das Problem darin, dass "marshal" Code-Objekte abbilden kann? Der Code wird schließlich beim Laden nicht ausgeführt.
Während Pickle nur Instanzen von existierenden Klassen erzeugt, kann marshal auch neuen Code einschleusen. Sobald du irgend etwas mit den Daten machst, werden Methoden wie __getattr__, __eq__ und co ausgeführt. Die Code-Objekte von Funktionen sind austauschbar.
Re: eval - nutzbar für sandbox?
Verfasst: Montag 15. November 2010, 18:46
von lunar
@Defnull: Verzeihe mir, doch ich sehe da noch immer kein Problem. Man hat dann nach "marshal.load()" eben ein Code-Objekt oder eine Liste derselben. Ja und? Dieses Code-Objekt ist ja per se nicht böse, sondern müsste erst einmal ausgeführt werden. Von selbst geschieht das nun allerdings nicht, es müsste im Quelltext zum Laden ja etwas der Art "foo.func_code = evil_code_object_from_marshal" stehen und das ist dann keine Unsicherheit in "marshal", sondern ein Fehler im Programm, welches Marshal nutzt.
Re: eval - nutzbar für sandbox?
Verfasst: Montag 15. November 2010, 18:51
von jtk
ok Danke ich komm wohl doch nicht drum herum, auf eunen "echten" prser zu nehmen - hatte ich beführchtet!
Re: eval - nutzbar für sandbox?
Verfasst: Montag 15. November 2010, 19:11
von lunar
@jtk: Du benötigst keinen eigenen Parser, sondern kannst auf das "ast"-Modul aufsetzen. Lediglich die Auswertung der Ausdrücke musst Du anschließend selbst implementieren, aber das ist nicht allzu schwer.
Re: eval - nutzbar für sandbox?
Verfasst: Montag 15. November 2010, 21:23
von Defnull
lunar hat geschrieben:@Defnull: Verzeihe mir, doch ich sehe da noch immer kein Problem. Man hat dann nach "marshal.load()" eben ein Code-Objekt oder eine Liste derselben. Ja und? Dieses Code-Objekt ist ja per se nicht böse, sondern müsste erst einmal ausgeführt werden. Von selbst geschieht das nun allerdings nicht, es müsste im Quelltext zum Laden ja etwas der Art "foo.func_code = evil_code_object_from_marshal" stehen und das ist dann keine Unsicherheit in "marshal", sondern ein Fehler im Programm, welches Marshal nutzt.
Du willst mit den Daten ja irgend etwas machen, nachdem du sie geladen hast, oder? Stell dir vor, du möchtest eine Liste aus der Datei laden. Stattdessen bekommst du ein Objekt, das __getitem__ implementiert und darin Schadcode ausführt. Oder __subclasscheck_ oder __instancecheck__.
Re: eval - nutzbar für sandbox?
Verfasst: Montag 15. November 2010, 22:03
von lunar
@Defnull: Laut Dokumentation funktioniert das nicht, da marshal nur bestimmte Typen unterstützt:
Not all Python object types are supported; …[…]. The following types are supported: booleans, integers, long integers, floating point numbers, complex numbers, strings, Unicode objects, tuples, lists, sets, frozensets, dictionaries, and code objects […]
Schlimmstenfalls also erhält man ein Code-Objekt selbst, aber niemals ein Objekt beliebigen Typs, dessen Methoden beliebige Code-Objekte haben. Anders gesagt, das marshal-Format kann keine Objekte mit beliebigen Methoden ala "Unterklasse von list mit bösen __getitem__()" beschreiben. Es beschreibt nur Code-Objekte selbst, man müsste das Code-Objekt also nachträglich manuell an eine Methode oder Funktion hängen, und das wird kaum jemand bei Verstand machen.
Re: eval - nutzbar für sandbox?
Verfasst: Montag 15. November 2010, 22:23
von ms4py
Pickle ist ebenfalls ziemlich gefährlich, was das Ausführen von Code betrifft. Hier ist man nur mit einer modifizierten `pickle.loads` auf der sicheren Seite, s.
http://docs.python.org/py3k/library/pic ... ng-globals.
Re: eval - nutzbar für sandbox?
Verfasst: Montag 15. November 2010, 22:39
von Defnull
lunar hat geschrieben:Anders gesagt, das marshal-Format kann keine Objekte mit beliebigen Methoden ala "Unterklasse von list mit bösen __getitem__()" beschreiben.
Stimmt. Das hatte ich anders im Gedächtnis. Unabhängig davon gilt marshal und Pickle aber nach wie vor als unsicher.