使用 php 为在线代码检查器进行安全系统调用


Secure system calls with php for an online Code Checker

虽然我知道系统调用和安全性不是齐头并进的,但有一个项目我确实需要它。我正在编写一个小的代码检查器,我需要编译并执行用户提交的代码以针对我的测试用例进行测试。

基本上我想在

沙箱中运行代码,这样它就不能接触临时目录之外的任何文件,它创建的任何文件都不能被外界访问。最近,我遇到了一个漏洞,用户可以使用该漏洞创建一个包含以下内容的文件,例如shell.php

<?php
  echo system($_GET['x']);
?>

这给了攻击者一个远程shell,并且由于文件的所有者是apache,攻击者基本上可以在存储mysql密码以及其他配置信息的整个/var/www中移动。

虽然我知道像SQL注入这样的威胁,并且在任何涉及数据库的操作之前已经清理了用户输入,但我不知道如何设置沙箱。我可以使用哪些技术来禁用系统调用(现在我正在用户提交的代码中搜索单词"system",而不是在找到它的地方执行那些代码片段)并限制对用户提交的代码创建的文件的访问。

到目前为止,我的代码检查器仅适用于C,我计划在保护它之后添加对其他语言的支持,如C++,Java,Ruby和Python。我也想了解更多关于我遇到的这个问题的信息,所以指向我可以了解更多关于 Web 安全的地方的指针也将不胜感激。

我的开发机器正在运行Mac OS Lion,部署机器是Linux服务器,因此,如果跨平台的解决方案将不胜感激,但仅处理Linux机器的解决方案也可以。

您可能想要做的是为运行脚本的用户在文件系统上的某个随机临时目录中设置一个 chroot。以下是一些关于设置 chroot 的阅读,以及一些安全知识。

我建议您也为Apache安装一个安全模块,例如suExec或MPM-iTK。然后,在 Apache 的虚拟主机中(如果您没有运行虚拟主机,请这样做!),分配一个特定的 UserID 来处理对这个特定虚拟主机的请求。这将请求与 Apache 默认用户分开,并增加了一点安全性。

    AssignUserID nonprivilegeduser nonprivilegeduser 

然后,通过设置以下 PHP 选项稍微强化 PHP,以便用户无法访问特定目录之外的文件,并在此目录中移动tmp_dirsession_save_path。这将阻止用户在其基目录之外进行访问。

    php_admin_value open_basedir /var/www/
    php_admin_value upload_tmp_dir /var/www/tmp
    php_admin_value session.save_path /var/www/tmp
与PHP

的行一起,阻止访问特定的函数和类,并阅读PHP的安全文章。

另外,我会让您调查该用户,禁用对sudosu的访问,以防止脚本尝试访问root权限。在此处了解更多信息。

总而言之,你说得又好又清楚。如果用户愿意,则无法完全阻止他们访问您的系统。诀窍是让它尽可能困难,并尽可能让他们感到困惑。

没有办法在跨平台的基础上完成这项工作,期间。沙盒本质上是高度特定于系统的。

在Mac OS X上,有沙盒功能。它的文档很少,但非常有效(谷歌浏览器严重依赖它)。一些有进取心的灵魂记录了其中的一部分。但是,它仅在Mac OS X上可用,因此可能会排除它。

在 Linux 上,您的选项开发得相当少。一些内核支持 seccomp 机制,以防止进程使用除一小组"安全"系统调用之外的任何调用;但是,并非所有人都这样做。此外,该"安全"子集不包括一些您可能需要的代码中的调用,这些调用尚未专门编写以在 seccomp 下运行 - 例如,不允许使用 mmapsbrk,因此您无法分配内存。不过,像seccomp-nurse这样的辅助工具可能会带你去某个地方。

以下是我建议做的事情。

1.禁用系统类和函数php.ini

disable_functions="system,curl_init,fopen..."
disable_classes="DirectoryIterator,SplFileObject..."

阿拉伯数字。在只读环境中运行,不存储任何重要数据。如果有人进入您的服务器,您不希望他们访问任何内容。一个好方法是购买 Amazon AWS EC2 并使用被监禁的用户来运行您的服务器和 PHP。

3.要求人们打破它。找到您不知道的缺陷和漏洞的唯一方法是找到它们。如有必要,请获取一个带有"测试"应用程序的临时服务器,该应用程序复制与"生产"环境相同类型的应用程序。

以下是一些有用的资源。

  • 要禁用的功能列表。它绝对可以扩展,但这是一个好的开始。
  • 有关避免安全问题的信息。
  • Viper-7代码板中的源代码和自述文件

我认为您正在寻找的是强制访问控制。在Linux中,它可以通过SeLinux获得。使用它,您可以限制谁可以执行什么命令。在您的情况下,您可以限制 php 用户(Apache)仅执行有限的命令,如 gcc 等。另请查看 AppArmor

另外,查看 runkit php 虚拟环境

您可以尝试在容器 (docker) 中运行用户提交的代码,这些容器是非常轻量级的 VM。它们在不到一秒钟的时间内开始。