Ich habe ein Projekt, in dem ich Benutzern erlauben muss, beliebigen, nicht vertrauenswürdigen Python-Code ( ein bisschen wie diesen ) auf meinem Server auszuführen . Ich bin ziemlich neu in Python und möchte Fehler vermeiden, die Sicherheitslücken oder andere Schwachstellen in das System einführen. Gibt es Best Practices, empfohlene Lektüre oder andere Hinweise, die Sie mir geben können, um meinen Service nutzbar zu machen, aber nicht missbräuchlich?
Folgendes habe ich bisher in Betracht gezogen:
- Entfernen Sie
__builtins__
aus demexec
Kontext, um die Verwendung von potenziell gefährlichen Paketen wie zu verbietenos
. Benutzer können nur Pakete verwenden, die ich ihnen zur Verfügung stelle. - Verwenden Sie Threads, um eine angemessene Zeitüberschreitung zu erzwingen.
- Ich möchte die Gesamtmenge an Speicher, die im
exec
Kontext zugewiesen werden kann, begrenzen , bin mir aber nicht sicher, ob dies überhaupt möglich ist.
Es gibt einige Alternativen zu einer Straße exec
, aber ich bin mir nicht sicher, welche davon hier hilfreich wäre:
- Verwenden von an
ast.NodeVisitor
, um jeden Versuch, auf unsichere Objekte zuzugreifen, abzufangen. Aber welche Gegenstände soll ich verbieten? - Suche nach doppelten Unterstrichen in der Eingabe. (weniger anmutig als die oben genannte Option).
- Benutze
PyPy
oder ähnliches wie Sandbox den Code.
HINWEIS: Mir ist bekannt, dass es mindestens einen JavaScript-basierten Interpreter gibt. Das wird in meinem Szenario nicht funktionieren.
quelle
Antworten:
Python Sandboxing ist schwer . Python ist von Natur aus auf mehreren Ebenen nachvollziehbar.
Dies bedeutet auch, dass Sie die Factory-Methoden für bestimmte Typen von diesen Typen selbst finden und neue Low-Level-Objekte erstellen können, die ohne Einschränkung direkt vom Interpreter ausgeführt werden.
Hier sind einige Beispiele für die Suche nach kreativen Möglichkeiten, um aus Python-Sandboxen auszubrechen:
Ned Batchelder beginnt mit einer Demonstration, wie gefährlich
eval()
wirklich ist .eval()
wird oft verwendet, um Python-Ausdrücke auszuführen; als primitiver und naiver Sandkasten für Einzeiler.Anschließend versuchte er weiterhin, die gleichen Prinzipien auf Python 3 anzuwenden , und gelang es schließlich , einige hilfreiche Hinweise herauszubrechen .
Pierre Bourdon verwendet ähnliche Techniken, um ein Python-System bei einem Hack-a-Thon zu hacken
Die Grundidee ist immer, einen Weg zu finden, um Basis-Python-Typen zu erstellen. Funktionen und Klassen und brechen Sie aus der Shell aus, indem Sie den Python-Interpreter veranlassen, beliebigen (ungeprüften!) Bytecode auszuführen.
Gleiches und mehr gilt für die
exec
Anweisung (exec()
Funktion in Python 3).Sie möchten also:
Kontrollieren Sie die Byte-Kompilierung des Python-Codes genau oder verarbeiten Sie den Byte-Code zumindest nach, um den Zugriff auf Namen zu verhindern, die mit Unterstrichen beginnen.
Dies erfordert genaue Kenntnisse über die Funktionsweise des Python-Interpreters und die Struktur des Python-Bytecodes. Codeobjekte sind verschachtelt. Der Bytecode eines Moduls deckt nur die oberste Ebene von Anweisungen ab. Jede Funktion und Klasse besteht aus einer eigenen Bytecode-Sequenz sowie Metadaten, die beispielsweise andere Bytecode-Objekte für verschachtelte Funktionen und Klassen enthalten.
Sie müssen Module, die verwendet werden können, auf die Whitelist setzen . Vorsichtig.
Ein Python-Modul enthält Verweise auf andere Module. Wenn Sie importieren
os
, enthältos
Ihr Modulnamensbereich einen lokalen Namen, der auf das Modul verweistos
. Dies kann einen entschlossenen Angreifer zu Modulen führen, die ihm helfen können, aus der Sandbox auszubrechen. Mit dempickle
Modul können Sie beispielsweise beliebige Codeobjekte laden. Wenn also ein Pfad durch auf der Whitelist befindliche Module zumpickle
Modul führt, haben Sie immer noch ein Problem.Sie müssen die Zeitkontingente streng einschränken. Selbst der neutralste Code kann immer noch versuchen, für immer zu laufen und Ihre Ressourcen zu binden.
Schauen Sie sich RestrictedPython an , das versucht, Ihnen die strikte Bytecode-Kontrolle zu geben.
RestrictedPython
wandelt Python-Code in etwas um, mit dem Sie steuern können, welche Namen, Module und Objekte in Python 2.3 bis 2.7 zulässig sind.Ob dies
RestrictedPython
für Ihre Zwecke sicher genug ist, hängt von den von Ihnen implementierten Richtlinien ab. Das Nichtzulassen des Zugriffs auf Namen, die mit einem Unterstrich beginnen, und das strikte Whitelisten der Module wären ein Anfang.Meiner Meinung nach ist die einzige wirklich robuste Option die Verwendung einer separaten virtuellen Maschine ohne Netzwerkzugriff auf die Außenwelt, die Sie nach jedem Durchlauf zerstören. Jedes neue Skript erhält stattdessen eine neue VM. Selbst wenn der Code aus Ihrer Python-Sandbox ausbricht (was nicht unwahrscheinlich ist), kann der Angreifer nur von kurzer Dauer und ohne Wert darauf zugreifen.
quelle
TL; DR Verwenden Sie eine Chroot / Jail und führen Sie sie als benutzerdefinierter Benutzer ohne Berechtigungen aus.
Die beste Praxis nicht vertrauenswürdigen Code für die Ausführung ist es über ein abzusondern System Sandbox. Für die meiste Sicherheit:
Sie befolgen auch die Standardverfahren zum sicheren Ausführen von Dingen in einer Chroot. Sie können das Dateisystem der Chroot auch bei jedem Aufruf neu erstellen, was besonders paranoid ist. Normalerweise können Benutzer das Dateisystem, in dem chroot ausgeführt wird, nicht ändern.
quelle
Auf keinen Fall können Sie dies sicher tun.
Wenn Sie so etwas sicher tun möchten, müssen Sie zunächst eine eigene Implementierung von Python haben, die in einer vollständig kontrollierten Umgebung ausgeführt wird, vorzugsweise im Browser des Benutzers statt auf Ihrem System. Sie können mit Jython (Python für Java) beginnen und es als Java-Applet verpacken. Da es in der Java-Sandbox auf dem Computer des Benutzers ausgeführt wird, ist Ihr System relativ sicher.
quelle
Wie Martijn oben sagte, ist dies in Python wirklich sehr, sehr schwierig. Ich halte es nicht für möglich, die Sprachfunktionen einzuschränken, da Python so nachvollziehbar ist. Und wenn Sie eine Sandbox für eine Python-Version zum Laufen bringen, besteht die Möglichkeit, dass die nächste Version diese kaputt macht.
Ich würde mir PyPy anstelle von Standard-CPython ansehen . Kurz gesagt, es ist eine kompatible alternative Implementierung von Python. Es hat mehrere Vorteile und unterschiedliche Funktionen, und eine davon ist das Sandboxing durch Ersetzen von Systemaufrufen, anstatt die Sprachfunktionen einzuschränken.
quelle
Solange die Leistung für Sie nicht besonders wichtig ist, können Sie sie immer in Brython ausführen, wodurch sie effektiv in die JavaScript-Sandbox eingefügt wird
quelle