防止Python代碼導入某些模塊?


Answers

你有沒有檢查過關於SandboxedPython的python.org 文章鏈接文章

這兩個頁面都鏈接到其他資源。

具體來說,PyPi的RestrictedPython可以讓你精確地定義可用的內容,並且有一些“安全”的默認值可供選擇。

Question

我正在編寫一個應用程序,用戶可以輸入一個python腳本並在沙箱中執行它。 我需要一種方法來防止exec'ed代碼導入某些模塊,所以惡意代碼不會有太多的問題。 有沒有辦法在Python中做到這一點?




不幸的是,我認為你所要做的是根本不可能的。 如果用戶可以在應用程序中執行任意代碼,那麼他們可以做任何他們想要的。 即使你能夠阻止他們導入某些模塊,也不會阻止他們自己編寫相應的功能(從頭開始或使用一些可用的模塊)。

我真的不知道在Python中實現一個沙箱的具體細節,但是我可以想像這是需要在解釋器級別完成的事情,並不容易!




8年了,沒有人想到這個呢? :/

您可以覆蓋import語句或者__import__函數。

這只是一個測試過的scribble-code,因為我找不到任何合法的參考:

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

這裡是該代碼的測試:

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

請不要評論我使用Python34,我有我的理由,這是我在Linux上的主要解釋器,專門用於測試我的主項目的東西(如上面的代碼)。