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

Bas*_*Ben 10 python security subprocess chroot jail

我正在编写一个基于Python的Web服务器,它应该能够执行"插件",以便可以轻松扩展功能.

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

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

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

由于插件代码来自不受信任的来源,我希望尽可能安全.我的想法是在子进程中执行代码,但是将它放入具有不同用户的chroot jail中,这样它就无法访问服务器上的任何其他资源.

不幸的是我找不到任何关于这一点,我不想依赖不受信任的脚本将自己置于监狱.

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

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

谢谢!

Log*_*gan 5

也许像这样?

# main.py
subprocess.call(["python", "pluginhandler.py", "plugin", env])
Run Code Online (Sandbox Code Playgroud)

然后,

# 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])
Run Code Online (Sandbox Code Playgroud)

编辑:想使用 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)
Run Code Online (Sandbox Code Playgroud)

很有用,我几乎只是偷了那个代码,所以感谢那个人提供了一个体面的例子。


wbe*_*rry 4

创建监狱后,您可以os.chroot从 Python 源调用以进入它。但即便如此,解释器已经打开的任何共享库或模块文件仍然会打开,而且我不知道通过关闭这些文件会产生什么后果os.close;我从来没有尝试过。

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

另一种方法是将不受信任的代码作为字符串读入,然后exec code in mynamespace在哪里mynamespace有一个字典,仅定义您想要向不受信任的代码公开的符号。这有点像 Python 虚拟机中的“监狱”。您可能必须首先解析源代码以查找import语句之类的内容,除非替换内置__import__函数会拦截该内容(我不确定)。