使用Scala解释器API时保护系统



我为 scala创建了简单的 REPL bot。

它在Linux环境中运行,并在对话框中编写的scala代码书写,并给出结果:

例如

user| 1+1
bot | res0: Int = 2
user| res0 + 3
bot | res1: Int = 5
...

我将Scala解释器API用于此目的。

代码将string作为Scala代码进行处理:

private val settings = new Settings
settings.processArgumentString(
    """
      |-deprecation
      |-feature
      |-Xfatal-warnings
      |-Xlint
      |-usejavacp
      |""".stripMargin)
def run(code: String, id: Long): (Result, String) = {
    stream.reset()
    try {
        val intp = intpMap.getOrElseUpdate(id, new IMain(settings, new PrintWriter(stream, true)))
        timedRun(maxWorkTime)(intp.interpret(code)) -> stream.toString
    } catch {
        case e: TimeoutException => (Error, s"Долго считать - иди в пень")
    }
}

但是,以下情况下是一个问题:如果用户尝试访问系统文件怎么办?例如,将写字符串:

scala.sys.process.stringToProcess("ls /").!!

bot将提供对系统文件的访问。我还在https://scastie.scala-lang.org/中尝试了此代码段,并可以访问系统文件。但是我认为他们在Docker容器中运行REPL,并且没有问题。

有什么方法可以限制运行机器人从访问系统文件中运行我的bot的JVM实例,或者我可以限制文件中的文件访问?

此时,我正在进行分析,给了" scala.sys"或" java.io"子字符串,但我认为这不是可靠的。

,安全中还有其他漏洞吗?

据我所知,解决方案构建到JVM为SecurityManager

您可以使用它来限制对JVM的各种功能的访问,例如限制对文件,请求,反射等的访问。但是我尚未对其进行测试(尤其是在REPP的背景下(,并且可能会发生您会发生遇到限制事物的问题,以无法阻止重复工作。

我认为会更安全的替代方案将您的替代作为一个单独的过程,而无访问在系统级别上 - 基本上创建一个非常有限的用户,在该过程中运行第二个JVM并通过某些RPC进行通信 - 这种方式操作系统本身将负责停止所有邪恶的用户的尝试。

尽管要更安全,但我将同时结合两者:在系统级别和SecurityManager中访问有限的访问权限。

正如您注意到Scastie所解决的那样,只需使用Docker解决此问题 - 如果您配置了Docker以限制CPU,内存和磁盘空间的每个图像的量,并且不会暴露任何从主机到图像的任何内容。

然后,您的"唯一"麻烦是像Meltdown/Specter这样的漏洞。但是在这一点上,您应该咨询一些安全专家,因为这可能太通用了。

最新更新