Python:使用chroot和chjail保护不受信任的脚本/子进程?

2024-04-25 07:28:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在写一个基于Python的web服务器,它应该能够执行“插件”,这样功能就可以很容易地扩展。

为此,我考虑了一种方法,即在其中包含多个文件夹(每个插件一个文件夹)和多个shell/python脚本,这些脚本以可能发生的不同事件的预定义名称命名。

一个例子是有一个on_pdf_uploaded.py文件,在将PDF上传到服务器时执行。为此,我将使用Python的子流程工具。

为了方便和安全起见,这将允许我使用Unix环境变量来提供进一步的信息,并设置进程的工作目录(cwd),以便它可以访问正确的文件,而无需找到它们的位置。

由于插件代码来自不受信任的源,我希望使其尽可能安全。我的想法是在一个子进程中执行代码,但是把它放在一个chroot监狱中,使用不同的用户,这样它就不能访问服务器上的任何其他资源。

不幸的是,我找不到关于这个的任何东西,我不想依赖不可信的脚本把自己关进监狱。

此外,我也不能将主进程/调用进程放入chroot监狱,因为当服务器响应其他请求时,插件代码可能同时在多个进程中执行。

所以这里有一个问题:如何在chroot监狱中以最低权限执行子进程/脚本,以保护服务器的其余部分不被错误的、不受信任的代码损坏?

谢谢你!


Tags: 文件方法代码功能服务器脚本文件夹插件
2条回答

创建监狱之后,您可以从Python源代码调用os.chroot进入监狱。但即使如此,任何已经由解释器打开的共享库或模块文件仍然是打开的,我不知道通过os.close关闭这些文件的后果是什么;我从未尝试过。

即使这样做有效,设置chroot也是一件大事,所以要确保收益物有所值。在最坏的情况下,您必须确保每个被监禁的文件系统中都有整个Python运行时以及您打算使用的所有模块、所有依赖程序和共享库以及来自/bin/lib等的其他文件。当然,这样做不会保护其他类型的资源,即网络目的地、数据库。

另一种方法是以字符串形式读入不受信任的代码,然后exec code in mynamespace,其中mynamespace是一个字典,仅定义要公开给不受信任的代码的符号。这可能是Python虚拟机中的一个“监狱”。您可能必须首先解析源代码,查找诸如import语句之类的语句,除非替换内置的__import__函数会截获它(我不确定)。

也许是这样的?

# main.py
subprocess.call(["python", "pluginhandler.py", "plugin", env])

那么

# pluginhandler.py
os.chroot(chrootpath)
os.setgid(gid) # Important! Set GID first! See comments for details.
os.setuid(uid)
os.execle(programpath, arg1, arg2, ..., env)
# or another subprocess call 
subprocess.call["python", "plugin", env])

编辑:想使用fork(),但我真的不明白它做了什么。查过了。新的 密码!

# main.py
import os,sys
somevar = someimportantdata
pid = os.fork()
if pid:
    # this is the parent process... do whatever needs to be done as the parent
else:
    # we are the child process... lets do that plugin thing!
    os.setgid(gid) # Important! Set GID first! See comments for details.
    os.setuid(uid)
    os.chroot(chrootpath)
    import untrustworthyplugin
    untrustworthyplugin.run(somevar)
    sys.exit(0)

This很有用,我刚刚偷了那段代码,这是一个很好的例子。

相关问题 更多 >