3

REPLscala.

它在 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 并且没有问题。

有什么方法可以限制运行我的机器人的 jvm 实例访问系统文件,或者我可以限制 REPL API 配置中的文件访问?

此时我正在为“scala.sys”或“java.io”子字符串的给定字符串进行分析,但我认为它不可靠。

还有其他安全漏洞吗?

4

1 回答 1

1

据我所知,构建到 JVM 中的解决方案是SecurityManager.

您可以使用它来限制对 JVM 的各种功能的访问,例如限制对文件、请求、反射等的访问。虽然我还没有测试过它(尤其是在 REPL 的上下文中),但您可能会遇到限制问题以一种根本不会阻止 REPL 工作的方式进行的事情。

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

尽管为了更安全,我会将两者结合起来:在单独的进程中运行 REPL,在系统级别以及SecurityManager.

正如您所注意到的,Scastie 只需使用 Docker 即可解决此问题 - 如果您将 Docker 配置为限制每个映像的 CPU、内存和磁盘空间量,并且不从主机向映像公开任何内容。

那么你的“唯一”麻烦就是像崩溃/幽灵这样的漏洞。但是此时,您应该咨询一些安全专家,因为 SO 可能对此过于笼统。

于 2019-05-23T15:28:20.140 回答