我正在使用 create_function 在服务器端运行一些用户代码。我正在寻找以下两个中的任何一个:
- 有没有办法清理传递给它的代码以防止执行有害的东西?
- 或者,有没有办法指定此代码在沙盒环境中运行,以便用户无法玩弄其他任何东西。
谢谢!
我正在使用 create_function 在服务器端运行一些用户代码。我正在寻找以下两个中的任何一个:
谢谢!
您可以使用tonkenizer确定代码将做什么,然后将某些功能和操作列入白名单。我认为最终很难(或不可能)使其万无一失,特别是考虑到 PHP 的灵活性:
$f = "shell_exec";
$arg = 'rm -rf /';
$f($arg); // ouch
call_user_func($f, $arg); // ouch
eval("$f('$arg');"); // ouch
$newF = create_user_function('', "$f('$arg');");
$newF(); // ouch
唯一可以为您提供 100% 安全性(嗯,99.9%...)的沙盒是您事后可以丢弃的虚拟机。
我们使用标记器静态分析代码,以及修改代码以对某些事物执行运行时检查。这是通过标记器和基于标记器的脚本完成的。由于标记器与 PHP 实际使用的标记器相同,因此与编写自己的标记器相比,它可以提高您的运气。
我见过人们使用正则表达式来尝试分析一种语言。这是一个非常糟糕的主意。
但 ...
由于 PHP 是一种非常简单的语法,并且您可以访问标记器,因此您实际上可以通过禁止变量函数并仅允许调用少量列入白名单的函数来阻止大部分错误。如果您不需要 OOP,那就更好了。
但是,我们没有足够的信心解决 100% 的问题,我们用它来为付费客户的后端用户提供沙箱,而不是地球上每个使用键盘的用户,也许还有恶意。
我也认为这里那些将想法 100% 视为“坏做法”的人需要得到线索。有理由这样做。
您可以尝试使用基于 Java 的 PHP 解释器 Quercus 来创建安全的沙盒 PHP 环境。你可以使用 Rhino 对 JavaScript 做同样的事情,所以我认为 Quercus 可能是可能的。
您无法可靠地清理用户输入 - 一个坚定的黑客会找到一些晦涩难懂的方法来规避您的清理代码。
沙盒是可能的,但同样严重。如果你真的想要安全,你应该为每个调用创建一个沙箱。毕竟,有人可以执行对您沙箱的所有其他用户有害的虚假代码。
我不认为你真的想允许这样做。可以这样想:您正在提供对服务器的编程访问!
您可以考虑创建一种用户可以使用的自定义(化)语言。然后由您来创建支持的函数库,这些函数库很可能只是 PHP 原生函数的包装器。但即便如此,使其免受黑客攻击或简单地工作充其量只是一项乏味的工作。或许您应该重新评估为什么希望用户首先拥有代码访问权限?如果您需要有人讨论这个问题,我很乐意提供帮助(或者更新您的问题,我猜?:)
希望你能解决!
-戴夫
这是 GitHub 上的一门课程,在早期阶段可能会有所帮助,但看起来很有希望。
总体而言,这是个坏主意,而且 IMO 太危险了,无论您采取了何种保护措施。更好地创建一种伪语言,仅限于允许用户做的事情。