Seite 1 von 1

Python Sandbox?

Verfasst: Sonntag 9. Dezember 2007, 11:31
von sma
Unter einer Sandbox verstehe ich eine eingeschränkte Ausführungsumgebung für Python-Scripte, sodass diese keinen Schaden (absichtlich oder unabsichtich sei egal) anrichten können. Gibt es so etwas bereits fertig (und getestet) für Python?

Bei `exec` könnte ich eine passend eingeschränkte Umgebung übergeben, in der keine potentiell gefährlichen Funktionen wie z.B. `eval` oder `exit` vorhanden sind.

Leider kann ich wohl nicht einen `import os` und danach einen Aufruf gefährlicher Funktionen verhindern. Den Codeschnipsel jetzt nach import-Anweisungen zu durchsuchen wirkt irgendwie unbeholfen. Desweiteren Überblicke ich zur Zeit nicht, ob die ganzen "under-under"-Attribute und Funktionen problematisch seinen könnten, sodass ich eigentlich lieber etwas von Ratiopharm benutzen möchte, als das selbst zu bauen.

Googlen hat einen Beitrag im Battle for Wesnoth-Forum gefunden. Das ganze wirkt aber irgendwie ad-hoc und nicht wirklich getestet. (Aber interessant zu wissen, dass dieses Spiel Python für KI benutzt ;)

Stefan

Verfasst: Sonntag 9. Dezember 2007, 11:49
von BlackJack
Ich würde sagen vergiss es. Es scheint sich bei ``exec`` in letzter Zeit etwas in der Richtung getan zu haben, aber solange nicht irgendwer von den Python-Entwicklern sagt, dass das zum Sandbox implementieren taugt…

Die dynamische Natur von Python, insbesondere der "introspection"-Teil macht Probleme.

Edit: Grammatik. Arghs. :-)

Verfasst: Sonntag 9. Dezember 2007, 12:32
von Leonidas
Es gab mal Bastion (und eine Reihe Vorgänger), aber letztendlich sind sie eben alle aus den von BlackJack angesprochenen Problemen gescheitert.

Verfasst: Sonntag 9. Dezember 2007, 18:10
von sma
Kennt jemand ein konkretes Beispiel für die angesprochenen "Probleme"? Ich würde das gerne verstehen.

Bei Bastion wird auf rexec verwiesen und dort steht auch nur was von "could be exploited by carefully written code". Das dies nicht gegen Endlosschleifen und übermäßige Speicheranforderungen hilft, mag ich noch akzeptieren. Da war Java auch nicht besser.

Stefan

Verfasst: Sonntag 9. Dezember 2007, 18:41
von Leonidas
Ok, habe etwas gesucht: Bug #577530, Ein Problem, Guidos Posting dazu ("big enough to drive an airplane carrier through" klingt schlimmer als "could be exploited by carefully written code").

Du kannst dir das Restricted Python von Zope ansehen, aber das ist so tief verwurzelt, dass sie es bisher nicht geschafft haben es auf Python 2.5 zu portieren.

Verfasst: Sonntag 9. Dezember 2007, 18:50
von BlackJack
Eventuell bringt eine Suche in der englischsprachigen Newsgroup was. Es gab/gibt wohl letztendlich immer irgend einen Weg an die "bösen" Funktionen heran zu kommen.

Verfasst: Sonntag 9. Dezember 2007, 23:44
von birkenfeld
PyPy kann sowas. :)

Verfasst: Montag 10. Dezember 2007, 00:16
von poker
http://home.vrweb.de/~juergen.katins/ru ... taint.html

Wäre doch mal ne alternative darüber nachzudenken auch sowas in Python zu implementieren? In Ruby funktioniert das **sehr** gut. allerdings weis ich nicht was für technische Schwierigkeiten es bei dem Python Code gibt, um sowas zu implementieren. -- Dazu kann sicherlich Georg was zu sagen.

Verfasst: Montag 10. Dezember 2007, 08:09
von mitsuhiko
poker hat geschrieben:Wäre doch mal ne alternative darüber nachzudenken auch sowas in Python zu implementieren? In Ruby funktioniert das **sehr** gut. allerdings weis ich nicht was für technische Schwierigkeiten es bei dem Python Code gibt, um sowas zu implementieren. -- Dazu kann sicherlich Georg was zu sagen.
In Python ist das aber wesentlich schwieriger als in Ruby. Ruby kennt das Konzept von Immutables nicht und damit kann man jede Variable tainten. Außerdem kannst du in Ruby nicht einfach auf Interpreter Internals zugreifen.

rexec Problem vereinfacht gesagt:

Code: Alles auswählen

exec (lambda:None).func_code.__class__(0, 1, 3, 67,
'd\x01\x00d\x00\x00k\x00\x00}\x00\x00|\x00\x00i\x01\x00d\x02\x00\x83\x01\x00\x01d\x00\x00S',
(None, -1, 'ls'), ('os', 'system'), ('os',), '<foo>', 'foo', 1, '\x00\x01\x0c\x01')
Zwar geht dieses Beispiel in rexec nicht, weil das funktionsobjekt auf <func_code> testet, aber es gibt Mittel und Wege auch das zu umgehen.