我在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.
用户可以在其帐户中拥有多个phpfiddles,每个phpfiddles对应随机目录,index.php
文件稍后通过<iframe>
执行。
如何避免任何应用用户可以通过index.php
文件创建/列出/删除其随机目录之外的任何文件/目录?
我目前的解决方案是解析PHP用户代码(在执行之前)并检测所有可能的函数,如file_put_contents()
,unlink()
,mkdir()
,dir()
,{{ 1}}和其他人,但这限制了测试的范围,我需要用户可以在上下文中使用这些函数。< / p>
我担心我需要根据资源执行情况“动态”设置文件系统的特殊权限(我猜)。怎么做?有可能实现这个目标吗?
编辑:目前php.net/runkit还不支持PHP 7(https://github.com/zenovich/runkit/issues/87),在这种情况下是必需的。
答案 0 :(得分:6)
实际上,没有。运行此类服务的安全隐患会导致执行不受信任的第三方代码,这需要大量的技术规划和基础架构。
要了解问题的严重程度,有一家公司提供此类服务(ideone.com,没有联属关系)。它的母公司Sphere Engine将此作为一种服务,在安全的环境中运行不受信任的代码。
特别是在Heroku上运行,如果被恶意使用(例如,使用PHP的邮件发送大量垃圾邮件(),使用PHP的CuRL通过DoS定位其他用户),您的服务可能会给您带来很多麻烦。这些问题只会延伸到一个用户删除另一个用户的文件,并可能会让你被Heroku禁止。恶意玩家可以并找出系统的方法。
-
为了更进一步,让我们考虑一下你理论上需要做些什么来完成这项任务。
你可以先使用Docker这样一个基本上像操作系统一样运行的容器。您需要配置环境,以便在容器上运行的代码不能访问Internet,CPU时间有限,并且在每次代码执行后都会被销毁。
每次用户提交代码时,您基本上都会将代码复制到容器中并允许代码运行。然后,您就可以捕获容器的输出并将其返回给用户。
这是对完成此任务所需要的粗略概述。
答案 1 :(得分:1)
您可以使用&#34; open_basedir&#34; PHP设置和包装执行的操作类似于:
ini_set('open_basedir', './fiddle');
include('fiddle/fiddle.php');
它将禁止小提琴访问其文件夹之外的文件系统。