Erkennen was ein Modul importiert

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
Gremlin
User
Beiträge: 166
Registriert: Freitag 28. Mai 2010, 23:49

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.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Das ist in einer dynamischen Sprache wie Python einfach unmöglich. Wenn du eine "sichere" Sprache haben willst musst du schon selbst eine entwickeln.
Gremlin
User
Beiträge: 166
Registriert: Freitag 28. Mai 2010, 23:49

Hm? Wieso soll das unmöglich sein?

Aus

Code: Alles auswählen

import foo
from foobar import bar
kann ich doch rauskriegen dass nun "foo" und "foobar" importiert wird??
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Was wenn jemand vorher PYTHONPATH setzt, sys.path verändert oder sys.meta_path nutzt? Was wenn jemand zum importieren __import__ nutzt?
Gremlin
User
Beiträge: 166
Registriert: Freitag 28. Mai 2010, 23:49

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. :roll: 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.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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?
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

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.
Gremlin
User
Beiträge: 166
Registriert: Freitag 28. Mai 2010, 23:49

@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. :oops:

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. :x
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'>]
Gremlin
User
Beiträge: 166
Registriert: Freitag 28. Mai 2010, 23:49

Ok, ich seh schon, mit der Verschlüsselung der Daten hab ich meine Möglichkeiten bereits ausgeschöpft. :|
Antworten