安全地在服务器上执行用户提交的Python代码

9 投票
4 回答
1837 浏览
提问于 2025-04-15 16:02

我正在考虑启动一个项目,这个项目需要执行用户通过HTML表单输入的Python代码。我知道这样做可能会很危险(因为使用了exec),但我见过至少有一个例子成功实现了。

我给Python Challenge的开发者发了一封邮件,他们告诉我他们使用的是自己想出来的解决方案,只透露他们使用了“操作系统提供的安全功能”,并且“操作系统(Linux)提供了大部分你需要的安全性,只要你知道怎么使用它”。

有没有人知道安全可靠的方法来实现这个呢?我考虑过为每次提交启动一个新的虚拟机,但这样会消耗太多资源,而且几乎不可能高效地实现。

4 个回答

2

如果你以用户 nobody 的身份在 Linux 上运行这个脚本,它几乎无法写入任何地方,也无法读取那些权限设置得当的数据。但它仍然可能造成拒绝服务攻击,比如:

  • 占满 /tmp 目录
  • 消耗所有的内存
  • 占用所有的 CPU 资源

此外,它还可以打开外部网络连接等等。你可能可以通过内核限制来锁定这些问题,但总会有一些东西你会忘记。

所以我认为,使用一个没有网络访问和真实硬盘的虚拟机是唯一(相对)安全的选择。也许 Python Challenge 的开发者使用的是 KVM,这在原则上是“由操作系统提供的”。

为了提高效率,你可以在同一个虚拟机中运行所有的提交。这可以节省很多开销,在最坏的情况下,它们只会互相影响,而不会影响到你的服务器。

3

http://codepad.org/about 成功地实现了这样一个系统(作为一个公共的代码粘贴和运行服务!)

codepad.org 是一个在线编译器/解释器,也是一个简单的协作工具。它就像一个可以执行代码的粘贴板。 [...]

它是如何工作的

代码的执行是由一个监督程序来处理的,这个程序基于 geordi。它的策略是通过一种叫做 ptrace 的方式来运行所有的代码,同时禁止或忽略很多系统调用。编译器和最终的可执行文件都在一个叫做 chroot 的沙箱里运行,并且有严格的资源限制。这个监督程序是用 Haskell 语言写的。

[...]

当你的应用涉及远程代码执行时,你必须考虑到安全问题。为了不单单依赖 chroot 和 ptrace 监督程序,我还采取了一些额外的安全措施:

  • 监督程序运行在虚拟机上,这些虚拟机有防火墙,无法进行外部连接。

  • 运行虚拟机的机器也有很强的防火墙,并且会定期从源镜像恢复。

3

在现代的Linux系统中,除了可以使用chroot(2)来限制进程外,还可以用clone(2)来代替fork(2)进一步限制进程。clone(2)有几个很有意思的选项:

CLONE_NEWIPC (new namespace for semaphores, shared memory, message queues)
CLONE_NEWNET (new network namespace - nice one)
CLONE_NEWNS (new set of mountpoints)
CLONE_NEWPID (new set of process identifiers)
CLONE_NEWUTS (new hostname, domainname, etc)

之前这个功能是在OpenVZ中实现的,后来被合并到了主流版本中,所以现在不需要再使用修改过的内核了。

撰写回答