einzelne Codeteile in einer Art Sandbox ausführen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
rookies
User
Beiträge: 8
Registriert: Samstag 27. November 2010, 14:37

Hi,
ich suche eine Möglichkeit, einzelne Teile eines Python-Scripts so auszuführen, dass sie keine Variablen vom Rest des Scripts auslesen und ändern können. Im Moment sieht der entsprechende Ausschnitt meines Codes so aus:

Code: Alles auswählen

# [...]
eineVariable = 7
exec(code)
print eineVariable
# [...]
Im Idealfall sollte dieses Script ja 7 ausgeben. Wenn aber jetzt der Inhalt von code z.B. so aussieht:

Code: Alles auswählen

eineVariable = 8
wird 8 ausgegeben und genau das will ich verhindern.

Ich hoffe mir kann jemand helfen. :)

Lg
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Du kannst bei exec einen Namensraum angeben.

Wofür möchtest du das denn haben?
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
rookies
User
Beiträge: 8
Registriert: Samstag 27. November 2010, 14:37

Danke, damit funktionierts perfekt. :)
Hätt ich doch noch mal nen Blick in die Python-Docs werfen sollen... :?

Lg
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Man beachte, dass "exec" oder "eval" in keiner Weise sicher ist. Es ist (ohne den CPython-Interpreter zu patchen) nicht möglich ist, eine "sichere" Sandbox in Python zu errichten. Die nächstbeste Lösung wäre, sich mit dem AST-Modul den abstrakten Syntaxbaum eines Codeschnipsels zu holen und dann diese Knoten per Hand unter Beachtung aller selbstauferlegter Restriktionen auszuwerten.

Stefan
rookies
User
Beiträge: 8
Registriert: Samstag 27. November 2010, 14:37

sma hat geschrieben:Man beachte, dass "exec" oder "eval" in keiner Weise sicher ist. Es ist (ohne den CPython-Interpreter zu patchen) nicht möglich ist, eine "sichere" Sandbox in Python zu errichten. Die nächstbeste Lösung wäre, sich mit dem AST-Modul den abstrakten Syntaxbaum eines Codeschnipsels zu holen und dann diese Knoten per Hand unter Beachtung aller selbstauferlegter Restriktionen auszuwerten.

Stefan
Ja, das ist mir schon klar. Es soll auch keine vollwertige Sandbox sein, eben nur „eine Art Sandbox“, die nur den Variablenzugriff regelt.

Lg
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

rookies hat geschrieben:Ja, das ist mir schon klar. Es soll auch keine vollwertige Sandbox sein, eben nur „eine Art Sandbox“, die nur den Variablenzugriff regelt.
Tut deine "Sandbox" doch auch schon nicht.
rookies
User
Beiträge: 8
Registriert: Samstag 27. November 2010, 14:37

DasIch hat geschrieben:Tut deine "Sandbox" doch auch schon nicht.
Wieso nicht? Der Vorschlag von jbs funktioniert bei mir.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Code: Alles auswählen

import __main__

__main__.eine_variable = 8
Sowas und andere Dinge klappen damit immer noch.
rookies
User
Beiträge: 8
Registriert: Samstag 27. November 2010, 14:37

DasIch hat geschrieben:

Code: Alles auswählen

import __main__

__main__.eine_variable = 8
Sowas und andere Dinge klappen damit immer noch.
Naja, OK, an so was hab ich nicht gedacht. Was meinst du genau mit „und andere Dinge“?

Lg
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Du kommst immer an den Typ eines Objektes, der Typ kennt alle Subklassen und die mro. Dementsprechend kann man in einem Interpreter so ziemlich alles veranstalten was man beliebt. PyPy hat zwar eine Sandbox aber die kuemmert sich auch nur um System Aufrufe und wuerde dieses Problem ebenfalls nicht beheben.

Die einzige sichere Loesung ist dementsprechend einen Interpreter zu embedden zum ausfuehren des Codes oder wie sma vorgeschlagen hat den AST vor dem ausfuehren zu analysieren.
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Vielleicht solltest du eher die Usereingabe interpretieren und selbst darauf reagieren.
Offensichtlich möchtest du hier den Benutzer etwas frei eingeben lassen, traust ihm aber nicht. Du kannst aber kaum alle Fälle bedenken und ausschließen die mit eval zu Lücken führen.
Abgesehen von Variablenänderungen sorgt z.B. die Eingabe von 45783385703750272057028721074157208457402385723804570287**870874028750248750238475027502572075023485780275017t502475025 in den Interpreter dazu, dass da ein Prozessor erst einmal gar nichts mehrt tut außer seeeehr viel zur rechnen.

Verzichte lieber darauf und interpretier die Eingabe selbst.

Gruß
Sparrow
rookies
User
Beiträge: 8
Registriert: Samstag 27. November 2010, 14:37

sparrow hat geschrieben:Verzichte lieber darauf und interpretier die Eingabe selbst.
Das geht leider nicht so einfach, da in dem Code vollwertiger Python-Code ist, also auch mit Verzweigungen (if, while, for, ...), Imports, usw.
DasIch hat geschrieben:Die einzige sichere Loesung ist dementsprechend einen Interpreter zu embedden zum ausfuehren des Codes oder wie sma vorgeschlagen hat den AST vor dem ausfuehren zu analysieren.
Dann werd ich mich doch mal an die AST-Lösung setzen. Danke erstmal für alle Antworten. :wink:

Lg
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Vielleicht hilft dir http://python-forum.de/viewtopic.php?p=147406#p147406, ich hatte da mal ein Beispiel gepostet und vielleicht war es das.

Stefan
Antworten