Wie kann ich die globals() kopieren?
@Alfons Mittelmeyer: Nochmal: Es haben schon Leute mit viel Erfahrung und guten Kenntnissen von der CPython-Implementierung versucht einen Sandkasten zu bauen und sind gescheitert. Ähnlich erging es dem `pysandbox`-Projekt wo der Entwickler nach drei Jahren mit der Erkenntnis aufgegeben hat dass das nicht möglich ist, und zwar weil sowohl Python's Introspection als auch die CPython-Implementierung darauf einfach nicht ausgelegt ist. Er war a) immer am hinterherfixen von Wegen aus der Sandbox auszubrechen und b) das Ergebnis war dann am Ende nicht mehr vernünftig nutzbar weil zu viel verboten werden muss.
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Ja Jerch, das mit eval wollte ich mal testen. Da hatte ich probiert:jerch hat geschrieben:Na dann, auf gehts:Code: Alles auswählen
eval("[k sbe k va bowrpg.__fhopynffrf__() vs 'mvcvzcbegre' va k.__anzr__]".decode('rot13'))
Code: Alles auswählen
print(eval("5+3"))
Man muss nur eval richtig definieren. Dazu braucht man eine Funktion:don't do this
don't do this
Code: Alles auswählen
def dont_do_this(*args):
print("don't do this")
return "don't do this"
Code: Alles auswählen
evcode = compile(code,filename,'exec')
my_scope = dict(globals())
my_scopel['eval'] = dont_do_this
my_scope['exec'] = dont_do_this
my_scope['compile'] = dont_do_this
exec(evcode,my_scope)
Auch print kann man verbieten, import aber nicht. Import ist ein großes Sicherheitsrisiko. Kann man natürlich mit find suchen, und dann nicht zulassen, was etwas importiert.
@Alfons Mittelmeyer: Deine Borniertheit nervt.
Und ja, diese Lücke läßt sich auch leicht stopfen, aber das Spiel kann man beliebig lange spielen.
Code: Alles auswählen
def dont_do_this(*args):
print("don't do this")
return "don't do this"
code = """print(eval.__globals__['__builtins__'].eval("5+3"))"""
evcode = compile(code,"",'exec')
my_scope = dict(globals())
my_scope['eval'] = dont_do_this
my_scope['exec'] = dont_do_this
my_scope['compile'] = dont_do_this
exec(evcode,my_scope)
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Wenn es so nicht weggeht, dann eben so:
Code: Alles auswählen
def exec_allowed(code):
forbidden = ('eval','import','compile','exec','__','globals','locals')
for entry in forbidden:
if code.find(entry) >= 0:
print('not allowed: ' + entry)
return
evcode = compile(code,"",'exec')
exec(evcode)
code = """print(eval.__globals__['__builtins__'].eval("5+3"))"""
exec_allowed(code)
@Alfons Mittelmeyer: das langweilt. Nicht nur, dass jetzt so gut wie kein Code mehr funktioniert, Deinem Ziel bist Du keinen Millimeter weit näher gekommen.
Code: Alles auswählen
code = """print(getattr(getattr(lambda:2,'_'+'_glob'+'als_'+'_')['_'+'_buil'+'tins_'+'_'],'ev'+'al')("5+3"))"""
@Alfons Mittelmeyer: Damit ist das aber immer noch nicht sicher. Falls Du jetzt versuchst das Katz und Maus-Spiel zu wiederholen was die Entwickler des Moduls aus der Standardbibliothek und von `pysandbox` jahrelang durchgemacht haben: Forsche da bitte selber nach. Du wirst das nicht sicher und benutzbar hinbekommen. Sehr wahrscheinlich nicht einmal sicher.
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Was heißt jahrelang durchmachen. Dass ich natürlich nur eine Beispiel gegeben hatte ist auch klar. Und dass lambda selbstverständlich auch nicht sein darf, weil das auch kompiliert, versteht sich auch. Also lambda sicher auch nicht - partial stelle ich natürlich dafür schon zur Verfügung. Und wenn Ihr noch ein paar Beispiele findet und man die ausschließt, dann ist sehr bald keines mehr da. Und getattr natürlich auch nikcht. So etwas wie Rechenoperationen, Stringoperationen oder len darf man n atürlich tun. type auch und print auch. Input aber wahrscheinlich nicht.
Zuletzt geändert von Alfons Mittelmeyer am Mittwoch 11. November 2015, 00:26, insgesamt 1-mal geändert.
Alfons "Don Quijote" und der Kampf gegen Python built-ins.
Was evtl. ginge - man baut eine eigene Import-Funktion per C-Modul und markiert die hierüber importierten Codeframes. Alle markierten Frames laufen in einem Whitelist-Kontext, oder halt früher noch per Ast-Auswertung ein eigenes Subset auf Parserebene verwalten. Du musst in jedem Fall an den Zustand des Interpreters ran und diesen irgendwie kontrollierbar halten. D.h. aber gleichzeitig, dass full-featured Python in Deinen remote-Importen nicht mehr möglich ist. Damit drehen wir uns im Kreis, das haben wir alles schonmal durchgekaut. Langsam habe ich das Gefühl, dass Du das Problemfeld nicht richtig verstehst.
Was evtl. ginge - man baut eine eigene Import-Funktion per C-Modul und markiert die hierüber importierten Codeframes. Alle markierten Frames laufen in einem Whitelist-Kontext, oder halt früher noch per Ast-Auswertung ein eigenes Subset auf Parserebene verwalten. Du musst in jedem Fall an den Zustand des Interpreters ran und diesen irgendwie kontrollierbar halten. D.h. aber gleichzeitig, dass full-featured Python in Deinen remote-Importen nicht mehr möglich ist. Damit drehen wir uns im Kreis, das haben wir alles schonmal durchgekaut. Langsam habe ich das Gefühl, dass Du das Problemfeld nicht richtig verstehst.
@Alfons Mittelmeyer: Eben das bald kein Beispiel mehr da sein wird ist ein Trugschluss und genau das heisst jahrelang durchmachen: Immer wenn die Entwickler sicher waren jetzt ist alles sicher kam dann doch wieder jemand mit einem Gegenbeispiel.
Du kannst auch nicht anhand von „Ich finde keine Beispiele mehr“ argumentieren es sei sicher, denn nur das Du oder jemand anders keine Lücken mehr findet beziehungsweise meldet, heisst ja nicht dass sie nicht mehr da sind. Der Entwickler von `pysandbox` war sich auch sehr sicher weil länger nichts mehr aufgefallen war — dann wurde das Projekt bei einer Challenge verwendet und schon während der ersten 24 Stunden gab es dann gleich zwei Codes die aus seinem Sandkasten ausbrachen.
Lern aus den Fehlern anderer und beschäftige Dich erst einmal selber in Ruhe für Dich mit dem Modul was mal in der Standardbibliothek war und mit `pysandbox` statt hier weiter zu trollen.
Du kannst auch nicht anhand von „Ich finde keine Beispiele mehr“ argumentieren es sei sicher, denn nur das Du oder jemand anders keine Lücken mehr findet beziehungsweise meldet, heisst ja nicht dass sie nicht mehr da sind. Der Entwickler von `pysandbox` war sich auch sehr sicher weil länger nichts mehr aufgefallen war — dann wurde das Projekt bei einer Challenge verwendet und schon während der ersten 24 Stunden gab es dann gleich zwei Codes die aus seinem Sandkasten ausbrachen.
Lern aus den Fehlern anderer und beschäftige Dich erst einmal selber in Ruhe für Dich mit dem Modul was mal in der Standardbibliothek war und mit `pysandbox` statt hier weiter zu trollen.
- pillmuncher
- User
- Beiträge: 1511
- Registriert: Samstag 21. März 2009, 22:59
- Wohnort: Pfaffenwinkel
Angenommen eine Funktion, die für jeden gültigen Pythonsatz True ausgibt, sofern dieser sicher importier-/compile-/exec-/evalbar ist und für jeden anderen gültigen Pythonsatz False. Das ist äquivalent dazu zu sagen, dass es zwei Sprachen SafePython und UnsafePython gibt mit einer Funktion, die True ausgibt, wenn ein gültiger Pythonsatz zur ersten Sprache gehört und False, wenn er zur zweiten Sprache gehört.
Der Satz von Rice besagt nun, dass es eine solche Funktion nicht im allgemeinen Fall geben kann. Anders ausgedrückt: es ist unentscheidbar, ob eine von irgendeiner Turingmaschine verstandene Sprache dieselbe ist wie SafePython. Außer natürlich, man beschränkt SafePython auf eine nicht-turingvollständige Teilmenge der gültigen sicheren Pythonsätze. Das heißt dann aber, es muss alles verboten werden, was irgendwie nützlich ist, Listen, Tupel, Sets, Dicts, Funktionsaufrufe, Objekte, File-IO, da man die alle benutzen kann, um rekursive Funktionsaufrufe durchzuführen oder zu simulieren, und damit hätte man wieder Turingvollständigkeit.
Oder anders gesagt: man bindet einfach keinen Fremdcode in sein Programm ein, wenn man der Quelle nicht trauen möchte.
Der Satz von Rice besagt nun, dass es eine solche Funktion nicht im allgemeinen Fall geben kann. Anders ausgedrückt: es ist unentscheidbar, ob eine von irgendeiner Turingmaschine verstandene Sprache dieselbe ist wie SafePython. Außer natürlich, man beschränkt SafePython auf eine nicht-turingvollständige Teilmenge der gültigen sicheren Pythonsätze. Das heißt dann aber, es muss alles verboten werden, was irgendwie nützlich ist, Listen, Tupel, Sets, Dicts, Funktionsaufrufe, Objekte, File-IO, da man die alle benutzen kann, um rekursive Funktionsaufrufe durchzuführen oder zu simulieren, und damit hätte man wieder Turingvollständigkeit.
Oder anders gesagt: man bindet einfach keinen Fremdcode in sein Programm ein, wenn man der Quelle nicht trauen möchte.
In specifications, Murphy's Law supersedes Ohm's.
- noisefloor
- User
- Beiträge: 3939
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
@Alfons Mittelmeyer: kennst du eigentlich das Buch "Fluent Python" oder besitzt es vielleicht sogar?
Gruß, noisefloor
@Alfons Mittelmeyer: kennst du eigentlich das Buch "Fluent Python" oder besitzt es vielleicht sogar?
Gruß, noisefloor
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
@noisefloor Das habe ich leider nicht. Aber sicher lohnenswert sich das anzuschaffen. Das wäre dann das erste Buch über Python, das ich dann lesen würde.
Es wäre nicht schlecht, wenn du das noch mit dem einen oder anderen machen würdest. Es ist immer ein bisschen schwierig über Dinge zu sprechen, die man nicht verstanden hat und trotzdem verteidigt.Alfons Mittelmeyer hat geschrieben:Das wäre dann das erste Buch über Python, das ich dann lesen würde.
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
@pillmuncher Es ist wohl das Beste keinen Code einzubinden dem man nicht traut. Hier im Forum war bisher niemand in der Lage, erklären zu können, weshalb man compile und exec als 'böse' ansieht. Es macht weniger wie import, es läßt sich mehr beschränken und außerdem hat man dann nicht durch eine Modul globale Definitionen und der Code wandert auch wieder in den Garbage Collector.
Es liegt doch vielmehr daran, dass Python an sich unsicher ist und anscheinend nicht sicher zu bekommen ist. Wenn man sich an die Regeln hält dass imports am Anfang stehen und kein exec und compile drin steht, dann sieht man, was eingebunden ist und wenn das dann nur Module sind, die man kennt, wie functools oder tkinter, dann ist man zufrieden.
Wenn man allerdings überall und unbegrenzt reinlädt, hat man keinen Überblick mehr, ob da auch etwas 'böses' dabei sein könnte.
Mit compile und exec, wenn man es selber benutzt, erhält man so etwas wie entfesseltes Python mit bielebiger Zuladung nur temporär benutzter Tools, die nach Gebrauch wieder in den Garbage Collector wandern. Auch ist es kein Problem, Fenster doppelt hinzuzuladen, ohne dass das Instanzen einer Klasse sind. Man hat dann einfach den Code doppelt im Speicher, der sich dann auch nicht in das Gehege kommt.
Allerdings liegt es wohl an der Unsicherheit von Python, dass man das gegenüber import auch nicht unsicherere compile und exec nicht mag, weil dann die Übersicht verloren geht, wo etwas geschieht.
Ein safe python wäre möglich, nämlich Syntax von python, also : und eingerückt statt { und }. Das wäre dann ziemlich abgespeckt und würde Vieles nicht bieten bzw. auch einschränken lassen.
Aber was nützt mir ein safe python, also etwas mit python Syntax, wenn es dafür keine tkinter Einbindung gibt. Python ist wohl nicht nur wegen seiner Syntax so beliebt, sondern auch wegen der Vielzahl der dazu vorhandenen Bibliotheken, die man einbinden kann. Ohne das und nur eine python Syntax hat man nicht viel.
Der Sandbox Weg - wobei man bei einigen Sandboxen nicht mal mehr ein Statement verwenden kann, sondern lambda dafür benutzen muss, hat sich nicht als besonders praktikabel herausgestellt.
Der gangbare Weg dagegen ist eine Sandbox, die auf einem sicheren OS beruht. Und wenn dann auch jemand das ganze Filesystem löschen würde, Na und? War eh nur temperär vorhanden und wird bei Programmende eh beseitigt.
Das ist der erfolgversprechende Weg, dass man Python ruhig machen läßt, was es will, nur raus aus dem OS kann es nicht und mehr als man dem OS erlaubt, kann es auch nicht.
Es liegt doch vielmehr daran, dass Python an sich unsicher ist und anscheinend nicht sicher zu bekommen ist. Wenn man sich an die Regeln hält dass imports am Anfang stehen und kein exec und compile drin steht, dann sieht man, was eingebunden ist und wenn das dann nur Module sind, die man kennt, wie functools oder tkinter, dann ist man zufrieden.
Wenn man allerdings überall und unbegrenzt reinlädt, hat man keinen Überblick mehr, ob da auch etwas 'böses' dabei sein könnte.
Mit compile und exec, wenn man es selber benutzt, erhält man so etwas wie entfesseltes Python mit bielebiger Zuladung nur temporär benutzter Tools, die nach Gebrauch wieder in den Garbage Collector wandern. Auch ist es kein Problem, Fenster doppelt hinzuzuladen, ohne dass das Instanzen einer Klasse sind. Man hat dann einfach den Code doppelt im Speicher, der sich dann auch nicht in das Gehege kommt.
Allerdings liegt es wohl an der Unsicherheit von Python, dass man das gegenüber import auch nicht unsicherere compile und exec nicht mag, weil dann die Übersicht verloren geht, wo etwas geschieht.
Ein safe python wäre möglich, nämlich Syntax von python, also : und eingerückt statt { und }. Das wäre dann ziemlich abgespeckt und würde Vieles nicht bieten bzw. auch einschränken lassen.
Aber was nützt mir ein safe python, also etwas mit python Syntax, wenn es dafür keine tkinter Einbindung gibt. Python ist wohl nicht nur wegen seiner Syntax so beliebt, sondern auch wegen der Vielzahl der dazu vorhandenen Bibliotheken, die man einbinden kann. Ohne das und nur eine python Syntax hat man nicht viel.
Der Sandbox Weg - wobei man bei einigen Sandboxen nicht mal mehr ein Statement verwenden kann, sondern lambda dafür benutzen muss, hat sich nicht als besonders praktikabel herausgestellt.
Der gangbare Weg dagegen ist eine Sandbox, die auf einem sicheren OS beruht. Und wenn dann auch jemand das ganze Filesystem löschen würde, Na und? War eh nur temperär vorhanden und wird bei Programmende eh beseitigt.
Das ist der erfolgversprechende Weg, dass man Python ruhig machen läßt, was es will, nur raus aus dem OS kann es nicht und mehr als man dem OS erlaubt, kann es auch nicht.
- noisefloor
- User
- Beiträge: 3939
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
Gruß, noisefloor
Aha... ob's als erstes Buch taugt weiß ich nicht, weil es schon sehr tief geht. Aber es würde definitiv dein Verständnis von Python _deutlich_ verbessern und viele deiner Fragen obsolet machen.@noisefloor Das habe ich leider nicht. Aber sicher lohnenswert sich das anzuschaffen. Das wäre dann das erste Buch über Python, das ich dann lesen würde.
Gruß, noisefloor
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Wenn es um Bücher ginge oder tieferes Verständnis. Leider hapert es schon an einfachem Verständnis. So sei compile und exec gefährlich, weil man damit auch die Festplatte löschen könnte. Und weil es damit gefährlich ist, muss man unbedingt import nehmen, so ist hier offensichtlich die Meinung. Ob man sich die Festplatte mit import löscht, oder mit compile und eval dürfte wohl ziemlich egal sein. Man soll eben nicht 'untrusted' code verwenden and das auch nicht oder sogar erst recht nicht mit 'import'.
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Bei Dir ja, darüber hinaus an Einsicht, Akzeptanz von allgemeinen und Python spezifischer Konventionen und der Bereitschaft, selber Ergebnis offen zu recherchieren.Alfons Mittelmeyer hat geschrieben: Leider hapert es schon an einfachem Verständnis.
Der Versuch, diese Aussage auf die vielen Regulars zu beziehen, die Dir natürlich oft widersprechen, grenzt schon an Unverschämtheit! Es gibt hier sehr viele User mit fundierten und tiefgreifenden Kenntnissen über Python und Informatik allgemein.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Richtig, es ist egal, ob man mit einem Trabbi, BWM oder Tesla versucht, über den Atlantik zu schippern. Man wird untergehen. Warum versuchst Du dennoch, mit einem Auto darüber zu kommen?Alfons Mittelmeyer hat geschrieben:Ob man sich die Festplatte mit import löscht, oder mit compile und eval dürfte wohl ziemlich egal sein.
Ist eine solche Analogie anschaulicher fürs einfache Verständnis?
- noisefloor
- User
- Beiträge: 3939
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
@Alfons Mittelmeyer: wenn compile und exec deine einzigen Problem sind und dein Python-Horizont an der Stelle endet dann brauchst du "Fluent Python" nicht. Spar' dir das Geld und geh' mal lecker Essen.
Gruß, noisefloor
@Alfons Mittelmeyer: wenn compile und exec deine einzigen Problem sind und dein Python-Horizont an der Stelle endet dann brauchst du "Fluent Python" nicht. Spar' dir das Geld und geh' mal lecker Essen.
Gruß, noisefloor
- pillmuncher
- User
- Beiträge: 1511
- Registriert: Samstag 21. März 2009, 22:59
- Wohnort: Pfaffenwinkel
Nicht Python an sich ist das Problem, sondern Turingvollständigkeit. Für keine turingvollständige Sprache kann man allgemein feststellen, ob sie irgendeine bestimmte nicht-triviale Eigenschaft (zB. "sicher" zu sein) besitzt. Schau dir das hier an, dann wird es klarer: https://www.youtube.com/watch?v=hN63FOa_Gp4Alfons Mittelmeyer hat geschrieben:[...] dass Python an sich unsicher ist und anscheinend nicht sicher zu bekommen ist.
In specifications, Murphy's Law supersedes Ohm's.