我需要阻止一些模块,我需要知道某个模块是否不导入它。所以我需要一种遍历所有模块的方法来查看模块是否有子模块,我需要阻止它。
有没有办法检查所有已安装的模块是否存在需要阻止的模块?我不需要跨平台解决方案。
答案 0 :(得分:2)
听起来你正试图build a sandbox。 Python wiki列出了一些good approaches。
我看了一下你的webapp,这很容易被黑客攻击:
ctypes.util
或logging
等模块或import os, sys
的数百个其他模块。x = [__import__("os")]
__builtins__['__import__']("os")
也适用这些只是我尝试过的第一件事。
如果您真的想这样做,那么唯一合理的方法就是建立一个白名单的安全模块。您必须通过每个模块的源并确定它们是否仅导入安全模块。
我不认为你可以在不改变Python解释器的情况下达到任何真正的安全性。有可能不那么明显的方法来掌握这些模块,你必须找到它们。
答案 1 :(得分: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
行为的方法来调用这个函数(我不希望这甚至是可能的,但值得研究)那么你可以允许文字的名字沿着危险的方向行进进口 - 以及允许人们使用他们喜欢的变量名称,这将使你更难弄清楚你正在采取什么措施来防止进口,从而绕过它......
答案 2 :(得分:1)
如果您正在尝试沙箱Python,我所知道的唯一真正的实现提供了这个没有OS支持的实现PyPy。一年或两年前在python-dev上有一个讨论沙盒的线程,人们通过窥视堆栈来获取无法进行本地导入的模块,字节码操作和其他一些东西,从而打破了所有尝试。
还讨论了一些额外的答案here。
答案 3 :(得分:0)
如果您只想阻止模块,您可以使用sys.path变量并使用它来确保它只包含列入白名单的模块(或排除列入黑名单的模块)。这样,Python解释器将无法找到不允许的模块,因此任何导入都将失败。
http://docs.python.org/tutorial/modules.html(参见6.1.2:“模块搜索路径”)