Seite 1 von 1
Erkennen was ein Modul importiert
Verfasst: Montag 31. Oktober 2011, 14:25
von Gremlin
Hallo zusammen,
ich würde gerne "registrieren" was ein Modul für Importe durchführen würde. Gibt es da andere Möglichkeiten als regex?
Warum ich das brauche:
Ich habe ein Modul dessen Inhalt ich nicht kenne. Dieses Modul soll importiert werden, das allerdings nur wenn es nichts "verbotenes" importiert. Ich muss also eine Auflistung der durchzuführenden Importe erhalten können, noch bevor das Modul tatsächlich importiert wird.
Re: Erkennen was ein Modul importiert
Verfasst: Montag 31. Oktober 2011, 14:45
von DasIch
Das ist in einer dynamischen Sprache wie Python einfach unmöglich. Wenn du eine "sichere" Sprache haben willst musst du schon selbst eine entwickeln.
Re: Erkennen was ein Modul importiert
Verfasst: Montag 31. Oktober 2011, 14:50
von Gremlin
Hm? Wieso soll das unmöglich sein?
Aus
kann ich doch rauskriegen dass nun "foo" und "foobar" importiert wird??
Re: Erkennen was ein Modul importiert
Verfasst: Montag 31. Oktober 2011, 14:55
von Hyperion
Schau Dir mal Abschnitt 30 in der Doku an "Importing Modules". Damit kann man ziemlich viel anstellen... und wie willst Du wirklich semantisch nachvollziehen, ob da eine eigene import-Routine mit implementiert wurde? Ok, dieses Modul muss man wohl auch erst mal mit "import" laden - aber da funzen denn ja doch nur RegExps, um das auszuschließen.
Re: Erkennen was ein Modul importiert
Verfasst: Montag 31. Oktober 2011, 14:56
von DasIch
Was wenn jemand vorher PYTHONPATH setzt, sys.path verändert oder sys.meta_path nutzt? Was wenn jemand zum importieren __import__ nutzt?
Re: Erkennen was ein Modul importiert
Verfasst: Montag 31. Oktober 2011, 15:21
von Gremlin
Hyperion hat geschrieben:Schau Dir mal Abschnitt 30 in der Doku an "Importing Modules".
Oh man.. der ModuleFinder.. ich glaubs einfach nicht. Danke!
Hyperion hat geschrieben:und wie willst Du wirklich semantisch nachvollziehen, ob da eine eigene import-Routine mit implementiert wurde?
Naja, um genau zu sein habe ich keine "verbotenen" Module, nur welche die "erlaubt" sind, includes also. Wenn da was dabei ist was nicht bekannt ist, wirds halt einfach nicht importiert (also das ganze Modul) und gut ist.
DasIch hat geschrieben:Was wenn jemand vorher PYTHONPATH setzt, sys.path verändert oder sys.meta_path nutzt? Was wenn jemand zum importieren __import__ nutzt?
Nunja, falls tatsächlich es jemand schafft sys.path bzw. sys.meta_path zu verändern bevor das Modul importiert wird, ist doch sowieso schon alles zu spät, oder etwa nicht? Und falls das ganze innerhalb des Moduls geschieht, muss dennoch "sys" importiert werden, was definitiv zu den nicht erlaubten gehören wird.

Falls dann noch jemand "__import__" nutzt wirds halt auch verhindert. Das ist ja ganz leicht mit einer Suche nach eben diesem Namen gelöst.
Inwieweit allerdings eine Umgebungsvariable wie PYTHONPATH nun eine Rolle spielt sehe ich gerade nicht.
Re: Erkennen was ein Modul importiert
Verfasst: Montag 31. Oktober 2011, 15:30
von snafu
Man könnte das Skript ja auch als Benutzer mit stark eingeschränkten Rechten ausführen. Dann sollte sich die Befürchtung, dass Schindluder via `sys` getrieben wird (z.B. Löschen von Dateien), einigermaßen erübrigt haben. Was ist denn der eigentliche Grund, warum du Module verbieten willst?
//edit: Ok, Löschen von Dateien ist in Bezug auf `sys` kein gutes Beispiel gewesen. Aber ich vermute, um solche Dinge geht's im Prinzip, oder?
Re: Erkennen was ein Modul importiert
Verfasst: Montag 31. Oktober 2011, 15:44
von DasIch
Gremlin hat geschrieben:Falls dann noch jemand "__import__" nutzt wirds halt auch verhindert. Das ist ja ganz leicht mit einer Suche nach eben diesem Namen gelöst.
Du kannst den Namen auch zur Laufzeit zusammensetzen.
Code: Alles auswählen
im = eval(''.join(['_', '_', 'i', 'm', 'p', 'o', 'r', 't', '_', '_']))
globals und __builtins__ bleiben auch noch.
Re: Erkennen was ein Modul importiert
Verfasst: Montag 31. Oktober 2011, 15:50
von Gremlin
@snafu
Nunja, es geht letztlich um das Thema ein Modul dynamisch zu laden. Also als Basis habe ich einen String, der repräsentiert Python Code und wird mittels "Exec string in dict" in ein Modul umgewandelt. In einem eigenen Prozess kann ich das schlecht ausführen, denn zum einen erhalte ich den String nicht von einem Dateiobjekt (müsst ich also auch erst erstellen) und zum anderen benötigt der Code innerhalb dieses Strings Zugriff auf aktuelle Daten der Laufzeit.
Da der eigentliche Prozess mit Admin-Rechten läuft ist das natürlich eine heikle Sache, dazu kommt noch dass der erwähnte String aus dem Netzwerk kommt, also wird die Sache noch heikler. Selbstverständlich läuft die Übertragung übers Netzwerk verschlüsselt ab, aber als weitere Vorsichtsmaßnahme dachte ich mir, ich schließe einfach aus dass bestimmte Dinge mit dem was da "blind" importiert wird gemacht werden können. Zuerst dachte ich da an eine eigene kleine Mini-Sprache die mittels pyparsing oder ähnlichem realisiert wird, aber nachdem das über einfache Anweisungen hinaus geht (Variablen, Typen, Bedingungen) wars mir doch etwas zu viel Aufwand.
Genau genommen gehts eigentlich nur, was mir jetzt so spontan einfällt, um die Blockade von socket, urllib(2) und ähnlichen Importen. Denn lesen und schreiben von Daten ist essentiell.
DasIch hat geschrieben:Du kannst den Namen auch zur Laufzeit zusammensetzen.
Gut, das Argument ist... vernichtend.

Re: Erkennen was ein Modul importiert
Verfasst: Montag 31. Oktober 2011, 16:30
von BlackJack
@Gremlin: Für Sockets brauchst Du nichts importieren wenn Dein Code das schon irgendwo vorher gemacht hat:
Code: Alles auswählen
python -c "import socket; print [o for o in object.__subclasses__() if 'socket' in o.__name__]"
[<class 'socket._closedsocket'>, <type '_socket.socket'>, <class 'socket._socketobject'>]
Re: Erkennen was ein Modul importiert
Verfasst: Montag 31. Oktober 2011, 17:49
von Gremlin
Ok, ich seh schon, mit der Verschlüsselung der Daten hab ich meine Möglichkeiten bereits ausgeschöpft.
