在执行用户上传的文件之前应该实施什么安全措施?

信息安全 C++ 编译器
2021-08-15 18:30:42

我想在我的网站上做一个小的编程难题。会有一个任务。将要求用户上传 C++ 源文件及其解决方案。该文件应该被编译,使用一些输入运行并检查它是否产生正确的输出。有哪些安全风险?如何确保上传的文件不会做任何恶意行为?

或者,有一些网站,比如Tutorials Point,可以让你编译和运行 C++ 代码。他们如何管理安全?

3个回答

分析一个程序以确定它是否会做任何恶意是不可能的。无论您是尝试分析源代码还是编译代码,这都是正确的。

通过在沙箱中编译和运行代码来完成您所要求的操作。一旦程序终止(或在您决定超时后),您将销毁沙箱。

这种构造的安全性与您使用的沙箱一样安全。根据运行沙箱所需的代码要求,可以是 Linux 安全计算模式等简单的东西,也可以是成熟的虚拟机等复杂的东西——最好没有网络连接。

您需要的沙箱越复杂,沙箱中的安全漏洞破坏其他良好设计的风险就越大。

某些语言可以在沙箱之外安全地编译。但是有些语言即使编译它们也会消耗不可预测的资源量。姊妹网站上的这个问题显示了一些小源代码如何爆炸成大输出的示例。

如果编译器本身没有漏洞,那么对允许使用的 CPU、内存和磁盘空间的数量设置限制就足够了。为了更好的安全性,您可以在虚拟机中运行编译器。

显然,这些方法可以组合起来以增加一层安全性。如果我要构建这样一个系统,我可能会启动一个虚拟机并在虚拟机内部使用 ulimit 来限制编译器的资源使用。然后我会将编译后的代码链接到一个包装器中,以便在安全计算模式下运行它。最后仍然在虚拟机内部,我将运行链接的可执行文件。

这是一个非常困难的问题,所有在线代码法官都必须解决。基本上,您是在问如何防止可以在您的机器上执行任意代码的人接管它。

我已经在在线法官 ( Kattis ) 上编码了十年左右,以下是我为这种场景构建安全解决方案的一些经验:

  1. 非常早期的版本是基于一个 solaris jail。事实证明,你可以在监狱内造成相当大的破坏,而且它并没有给你所需的粒度。
  2. 我们使用 ptrace 实现了一个系统调用过滤解决方案。这在系统调用上引入了非常(几个上下文切换)的大量开销,并且在编译器和运行器更改时保持安全配置文件同步是一场噩梦。这个解决方案的最后一个钉子是穿线。如果您允许线程,应用程序可以使用线程来重写检查和执行之间的系统调用,例如 Java 需要线程。
  3. 这些天来,我们使用 cgroups 和命名空间的组合。这提供了令人惊讶的低开销,并且由于它们是 Linux 内核中安全原语的一部分,因此它们很健壮。查看MOE Isolate了解如何做到这一点。隔离最有可能解决您的问题。

请注意,虽然 docker 或虚拟机等容器很受欢迎,但在这种情况下,它们可能不是安全解决方案的最佳选择。很难获得您可能想要的细粒度控制和资源监控,很难防止恶意进程在您的容器内乱搞,并且启动和销毁容器会产生很多开销。

在拼图网站的特殊情况下,请考虑替代方案:不要打扰。要求参与者上传输出,这样您就不必运行不受信任的代码。这可以节省您的计算能力,避免安全风险,并允许人们以任何语言进行竞争。如果有奖品,您可以稍后手动验证中奖条目。

如果您的拼图形式允许,您可以通过生成随机输入和编写验证程序来挫败复制粘贴解决方案。这就是 Google Code Jam 的工作原理。请参阅https://code.google.com/codejam/problem-preparation.html#iogen