有没有办法遍历所有可以导入的模块

发布于 2024-10-21 22:13:57 字数 117 浏览 3 评论 0 原文

我需要阻止某些模块,并且需要知道某些模块是否不导入它。所以我需要一种方法来遍历所有模块以查看模块是否有我需要阻止的子模块。

有没有办法检查所有已安装的模块是否存在我需要阻止的模块?我不需要跨平台解决方案。

I need to block some modules and I need to know if some module don't import it. So I need a way to traverse all modules to see if a module have sub module, that I need to block.

Is there a way to check all installed modules for existence of modules I need to block? I don't need cross-platform solution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

往昔成烟 2024-10-28 22:13:57

听起来您正在尝试构建沙箱。 Python wiki 列出了一些 好的方法

我查看了您的 web 应用程序,它很容易被破解:

  • 您可以导入 ctypes.util 或logging 等模块或数百个导入 os、sys 的模块。
  • 您甚至可以直接导入模块,例如 x = [__import__("os")]
  • __builtins__['__import__']("os") 也可以

,这些只是我尝试的第一件事。

如果您确实想这样做,那么唯一合理的方法是构建安全模块白名单。您必须仔细检查每个模块的源并确定它们是否仅导入安全模块。

不过,我认为如果不更改 Python 解释器,就无法实现任何真正的安全性。可能有一些不太明显的方法来获取这些模块,您必须找到所有这些模块。

Sounds like you're trying to build a sandbox. The Python wiki lists some good approaches.

I took a look at your webapp and it's quite easy to hack:

  • you can import modules like ctypes.util or logging or hundreds of others that import os, sys.
  • you can even import the modules directly like x = [__import__("os")]
  • __builtins__['__import__']("os") works too

and those are just the first things I tried.

If you really want to do this then the only reasonable approach is to built a whitelist of safe modules. You have to though the sources for each module and determine if they import only safe modules.

I don't think you can reach any kind of real security without changing the Python interpreter though. There are probably way less obvious ways to get a hold of these modules and you'd have to find them all.

月亮坠入山谷 2024-10-28 22:13:57

这将防止 @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...
>>>  

但是它不会更改默认的导入行为。看来您不再是其中包含名称“os”的文字了。如果您可以找到一种编辑实际 import 行为来调用此函数的方法(我不希望这是可能的,但值得研究),那么您可以允许沿危险的导入行 - 以及允许人们使用他们喜欢的变量名称,这将使你更难弄清楚你正在做什么来阻止导入,从而绕过它......

This will prevent the behaviour @Jochen observed (assuming you populate your list a little more fully)

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)

Trying it on your site gives:


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

It doesn't however change the default import behaviour. It looks like you're stopping there from being a literal with the name 'os' in it. If you can find a way of editing the actual import behaviour to call this function (I'm not hopeful that this is even possible, but it's worth looking into) then you can allow literals with names along the lines of dangerous imports - as well as allowing people to use variable names that they like, this will make it harder to work out what you're doing to prevent imports, and therefore getting around it...

︶葆Ⅱㄣ 2024-10-28 22:13:57

如果您尝试对 Python 进行沙箱处理,据我所知,在没有操作系统支持的情况下提供此功能的唯一真正实现是 PyPy。一两年前,python-dev 上有一个讨论沙箱的帖子,人们通过执行诸如查看堆栈以获取无法本地导入的模块、字节码操作和其他一百种事情等方式打破了所有尝试。

此处还讨论了一些额外的答案。

If you are trying to sandbox Python, the only real implementation I know of that provides this without OS support is PyPy. There was a thread on python-dev a year or two ago discussing sandboxing and people broke all the attempts by doing things like peeking into the stack to obtain modules that couldn't be locally imported, bytecode manipulation and a hundred other things.

A couple of extra answers are discussed here as well.

夏雨凉 2024-10-28 22:13:57

如果您只想阻止模块,您可以使用 sys.path 变量并使用它来确保它仅包含白名单模块(或排除黑名单模块)。这样,Python 解释器将无法找到不允许的模块,因此这些模块的任何导入都会失败。

http://docs.python.org/tutorial/modules.html(参见 6.1。 2:“模块搜索路径”)

If you just want to block modules, you may be able to play with sys.path variable and use it to make sure that it only contains whitelisted modules (or excludes blacklisted ones). This way the Python interpreter won't be able to find disallowed modules and therefore any import of those will fail.

http://docs.python.org/tutorial/modules.html (see 6.1.2: “The Module Search Path”)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文