español __name__ __main__ python module sandbox

python - if__name__== ''__main__'' español



¿Evitar que el código de Python importe ciertos módulos? (6)

Estoy escribiendo una aplicación donde los usuarios pueden ingresar un script de python y ejecutarlo en un sandbox. Necesito una forma de evitar que el código ejecutado importe ciertos módulos, por lo que el código malicioso no será un gran problema. ¿Hay alguna manera de hacer esto en Python?



El SDK de código abierto de Google App Engine tiene una implementación detallada y sólida de mecanismos para detener la importación de módulos no deseados (para ayudar a detectar códigos que intentan importar módulos que no están disponibles en las instancias de producción de App Engine), aunque incluso eso podría ser subvertido si el código de usuario era malo en lugar de simplemente erróneo (las instancias de producción obviamente tienen más capas de defensa, como simplemente no tener esos módulos en absoluto ;-).

Entonces, todo depende de cuán profunda debe ser su defensa. En un extremo, simplemente __import__ el __import__ incorporado en otro lugar y lo reemplaza con su función que realiza todas las comprobaciones que desea antes de delegar en __builtin__ ; eso es quizás 20 líneas de código, 30 minutos para implementar y probar a fondo ... pero puede que no te proteja por mucho tiempo si alguien me ofrece un millón de dólares para entrar en tu sistema (y, hipotéticamente, yo no fui el bueno ... dos-zapatos tipo de chico que en realidad soy, por supuesto ;-). En el otro extremo, despliega una serie profunda de capas de defensa que podrían tomar miles de líneas y semanas de implementación y prueba, dado el tipo de presupuesto de recursos, podría implementar algo que no podría penetrar (pero hay siempre el riesgo de que alguien más sea más inteligente y más experto en Python que yo, ¡por supuesto!).

Entonces, ¿a qué profundidad quieres ir, o más bien, qué tan profundo puedes PERMITIR que vayas ...?


Lamentablemente, creo que lo que intentas hacer es fundamentalmente imposible. Si los usuarios pueden ejecutar código arbitrario en su aplicación, entonces pueden hacer lo que quieran. Incluso si pudieras evitar que importen ciertos módulos, no habría nada que les impida escribir ellos mismos la funcionalidad equivalente (desde cero o utilizando algunos de los módulos que están disponibles).

Realmente no conozco los detalles de la implementación de un sandbox en Python, pero me imagino que es algo que debe hacerse a nivel de intérprete y no es nada fácil.


Puede sobrecargar el mecanismo de importación. Usamos esto para tener un sistema de licencias para complementos, puede tener fácilmente una lista blanca / lista negra de nombres de módulos.


Si coloca None en sys.modules para un nombre de módulo, in no será importable ...

>>> import sys >>> import os >>> del os >>> sys.modules[''os'']=None >>> import os Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named os >>>


8 años, yeesh, ¿y nadie ha descubierto esto? : /

Puede anular la declaración de import o la función __import__ .

Esto es solo un código de garabato probado porque no pude encontrar ninguna referencia legítima:

import importlib def secure_importer(name, globals=None, locals=None, fromlist=(), level=0): if name != ''C'': print(name, fromlist, level) # not exactly a good verification layer frommodule = globals[''__name__''] if globals else None if name == ''B'' and frommodule != ''C'': raise ImportError("module ''%s'' is restricted."%name) return importlib.__import__(name, globals, locals, fromlist, level) __builtins__.__dict__[''__import__''] = secure_importer import C

y aquí están las pruebas para ese código:

Python 3.4.3 |Anaconda 2.3.0 (32-bit)| (default, Mar 6 2015, 12:08:17) [MSC v.1600 32 bit (Intel)] on win32 Type "copyright", "credits" or "license()" for more information. >>> ================================ RESTART ================================ >>> B (''f'',) 0 imported secure module >>> from B import f B (''f'',) 0 linecache None 0 encodings.utf_8 [''*''] 0 Traceback (most recent call last): File "<pyshell#0>", line 1, in <module> from B import f File "/home/tcll/Projects/python/test/restricted imports/main.py", line 11, in secure_importer raise ImportError("module ''%s'' is restricted."%name) ImportError: module ''B'' is restricted. >>> import C >>>

Por favor, no comenten sobre mí usando Python34, tengo mis razones, y es mi intérprete principal en Linux específicamente para probar cosas (como el código anterior) para mi proyecto principal.