如何防止用户操纵文件系统

How to prevent file system manipulation by an User

信息

我在 Heroku 中有一个 phpfiddle 应用程序,用户可以在其中使用任何 php 代码。

基本上这是应用程序结构(示例):

/app/
|
|--fiddle/ <-- contains all php fiddles generated by the user.
|  |
|  |-- abcde/ <-- random directory.
|      |
|      |--index.php <--- custom user code.
| 
|--app.php <--- entry point and main app file.

用户可以在他们的帐户中有多个phpfiddle,每个对应一个随机目录index.php稍后通过 <iframe> 执行文件。

问题

如何避免任何应用程序用户可以通过 index.php 文件 Create/List/Delete 任意 file/directory 其随机目录之外的任何内容?

研究

我目前的解决方案是解析 PHP 用户代码(在执行之前)并检测所有可能的函数,如 file_put_contents()unlink()mkdir()dir()rmdir() 和其他,但这限制了 测试的范围 我需要用户可以玩 这些 功能在他们的 上下文中 .

恐怕我需要根据资源执行设置文件系统的特殊权限"dynamically"(我猜)。怎么做?有可能实现吗?

编辑: 目前 php.net/runkit does not support PHP 7 yet (https://github.com/zenovich/runkit/issues/87) 在这种情况下是必需的。

实际上,没有。运行在这样的服务中执行不受信任的第三方代码的安全隐患需要大量的技术知识规划和基础设施。

要了解问题的严重性,有一家公司提供此类服务(ideone.com,无隶属关系)。它的母公司 Sphere Engine 将此作为服务提供给安全环境中的 运行 不受信任的代码。

尤其是在 Heroku 上 运行ning,如果您的服务被恶意使用(例如使用 PHP 的 mail() 发送大量垃圾邮件,针对其他用户使用 PHP 的 CuRL 通过 DoS)。这些问题会扩展到一个用户删除另一个用户的文件,并且可能会让你被 Heroku 禁止。恶意行为者可以并且将会找出绕过您系统的方法。

--

为了更进一步,让我们考虑一下理论上您需要做什么才能完成这样的任务。

您将从使用 Docker 之类的东西开始,这是一个本质上 运行 类似于操作系统的容器。您需要配置环境,使容器上的代码 运行ning 无法访问互联网,在 CPU 时间内受到限制,并在每次代码执行后被销毁。

每次用户提交代码时,您基本上都会将代码复制到容器中并允许代码 运行。然后,您将能够捕获容器的输出,并 return 将其提供给用户。

这是完成此任务所需条件的粗略概述。

您可以使用“open_basedir”PHP 设置和 wrapp fiddle 执行,例如:

ini_set('open_basedir', './fiddle');
include('fiddle/fiddle.php');

它将禁止 fiddles 访问其文件夹之外的文件系统。