Wie kann ich die globals() kopieren?

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.
BlackJack

@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.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

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'))
Ja Jerch, das mit eval wollte ich mal testen. Da hatte ich probiert:

Code: Alles auswählen

print(eval("5+3"))
Und was kam raus? Das da:
don't do this
don't do this
Man muss nur eval richtig definieren. Dazu braucht man eine Funktion:

Code: Alles auswählen

def dont_do_this(*args):
    print("don't do this")
    return "don't do this"
Und dann schreibt man:

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)
Da siehst Du wie gut compile und exec und eval funktioniert :wink:

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.
Sirius3
User
Beiträge: 18051
Registriert: Sonntag 21. Oktober 2012, 17:20

@Alfons Mittelmeyer: Deine Borniertheit nervt.

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)
Und ja, diese Lücke läßt sich auch leicht stopfen, aber das Spiel kann man beliebig lange spielen.
Alfons Mittelmeyer
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)
Sirius3
User
Beiträge: 18051
Registriert: Sonntag 21. Oktober 2012, 17:20

@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"))"""
BlackJack

@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.
Alfons Mittelmeyer
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.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

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.
BlackJack

@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.
Benutzeravatar
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.
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
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
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.
Benutzeravatar
sparrow
User
Beiträge: 4361
Registriert: Freitag 17. April 2009, 10:28

Alfons Mittelmeyer hat geschrieben: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
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.
Benutzeravatar
noisefloor
User
Beiträge: 3939
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
@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.
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.

Gruß, noisefloor
Alfons Mittelmeyer
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'.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Alfons Mittelmeyer hat geschrieben: Leider hapert es schon an einfachem Verständnis.
Bei Dir ja, darüber hinaus an Einsicht, Akzeptanz von allgemeinen und Python spezifischer Konventionen und der Bereitschaft, selber Ergebnis offen zu recherchieren.

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
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Alfons Mittelmeyer hat geschrieben:Ob man sich die Festplatte mit import löscht, oder mit compile und eval dürfte wohl ziemlich egal sein.
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?
Ist eine solche Analogie anschaulicher fürs einfache Verständnis?
Benutzeravatar
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
Benutzeravatar
pillmuncher
User
Beiträge: 1511
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Alfons Mittelmeyer hat geschrieben:[...] dass Python an sich unsicher ist und anscheinend nicht sicher zu bekommen ist.
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_Gp4
In specifications, Murphy's Law supersedes Ohm's.
Antworten