有没有办法遍历所有可导入的模块
我需要阻止一些模块的使用,并且想知道某个模块是否没有引入这些模块。所以我需要一种方法,能遍历所有模块,看看某个模块是否有我需要阻止的子模块。
有没有办法检查所有已安装的模块,看看是否存在我需要阻止的模块?我不需要跨平台的解决方案。
4 个回答
2
听起来你想要建立一个沙盒环境。Python的维基上列出了一些不错的方法。
我看了你的网页应用,发现它很容易被攻击:
- 你可以导入像
ctypes.util
、logging
这样的模块,还有成百上千个其他模块,它们都可以通过import os, sys
来导入。 - 你甚至可以直接导入模块,比如
x = [__import__("os")]
__builtins__['__import__']("os")
也可以用
这些只是我尝试的第一些方法。
如果你真的想做到这一点,唯一合理的办法就是建立一个白名单,列出安全的模块。不过,你需要查看每个模块的源代码,确认它们只导入安全的模块。
不过,我觉得如果不改变Python解释器,你是无法达到真正的安全性的。可能还有很多不明显的方法可以获取这些模块,你得把它们都找出来。
1
这样做可以避免@Jochen观察到的情况(前提是你稍微多填充一下你的列表)
def __import__(name, globals={}, locals={}, fromlist=[], level=-1, oldfunc=__import__):
checklist = fromlist[:]
checklist.extend(name.split('.'))
for check in checklist:
if check in ('os', 'sys'):
print 'Uh-uh I\'m better than that...'
return
oldfunc(name, globals, locals, fromlist, level)
在你的网站上试试会得到:
>>> def __import__(name, globals={}, locals={}, fromlist=[], level=-1, oldfunc=__import__):
checklist = fromlist[:]
checklist.extend(name.split('.'))
for check in checklist:
if check in ('os', 'sys'):
print 'Uh-uh I\'m better than that...'
return
oldfunc(name, globals, locals, fromlist, level)
>>> __import__('os')
Uh-uh I'm better than that...
>>> x = [__import__('os')]
Uh-uh I'm better than that...
>>>
不过,这并不会改变默认的import
行为。看起来你是阻止了名称中包含'os'的字面量。如果你能找到一种方法来编辑实际的import
行为,使其调用这个函数(我对这是否可能不抱太大希望,但值得一试),那么你就可以允许一些像危险导入这样的名称字面量,同时也让人们可以使用他们喜欢的变量名,这样就更难判断你是如何防止导入的,从而也就更难绕过这个限制……