如何防止Python代码导入某些模块?

28 投票
6 回答
29833 浏览
提问于 2025-04-15 13:57

我正在写一个应用程序,用户可以在里面输入Python脚本并执行。为了安全起见,我需要一种方法来阻止这些执行的代码导入某些模块,这样恶意代码就不会造成太大问题。请问在Python中有没有办法做到这一点?

6 个回答

14

哎呀,八年了,居然还没有人搞明白这个问题?:/

你可以重写 import 语句,或者说是 __import__ 函数。

这只是我测试过的简单代码,因为我找不到任何靠谱的参考资料:

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 上主要用来测试东西(就像上面的代码)的一种解释器,特别是为了我的主要项目。

19

你有没有去看一下python.org上关于SandboxedPython的文章,还有那个相关链接的文章

这两页都有其他资源的链接。

特别是,PyPi上的RestrictedPython可以让你精确地定义哪些东西是可以使用的,并且提供了一些“安全”的默认选项供你选择。

35

如果你在 sys.modules 里把某个模块的名字设置为 None,那么这个模块就无法被导入了...

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

撰写回答