security - 如何构建一个安全的(受限生态系统)基于插件的架构(在 Kotlin 中)

标签 security kotlin plugins jvm sandbox

所以我主要尝试简单的架构,我在其中创建一个通用接口(interface)的 repo,然后将其拉到每个插件上,然后实现它,然后调用主应用程序以添加插件并在运行时动态运行它。

interface PluginI {
    val core: CoreApplication   // Means of communication with core app, this obj is sent by core app by constructor

    fun version(): Double
    suspend fun load(pluginConfiguration: PluginConfiguration)
    suspend fun run()
}

But how should the plugin be restricted to some area, such as protection from potentially destroying, hijacking or crashing the main app? Especially it should be restricted from using anything from jvm's static classes such as System, an example of some hijacking app is that it could do a System.getRuntime().exec() which could be execute exploits in shell.

沙盒不是解决方案,是吗?因为它只是中断了主应用程序和插件之间的连接。

我正在寻找一种解决方案,该解决方案提供一个共享对象,主应用程序通过该共享对象与插件进行通信并发送它想要的一些信息,例如日期/时间或任何不会影响运行时的信息。

最佳答案

在 java 中创建沙盒环境几乎是不可能的,对于 java 9+,您可以使用模块使这更容易一些......特别是如果您想要允许某种反射。

但是允许反射真的很难而且有风险,你所做的一切都应该作为白名单,黑名单只是“不起作用”(也就是说,我不相信任何人都能找到所有的东西包括并记住在更新任何依赖项时保持更新)。

Java 有一个用于此类东西的内置系统,它称为 SecurityManager,您的应用程序应该设置自己的 SecurityManager 并使用它来过滤每个方法调用,并且只允许从调用它的同一插件调用方法并阻止任何类型的反射,阻止更改安全管理器并阻止任何手动类加载。

此外,java 9 模块可用于简化此设置,因为模块甚至可以阻止模块之间的调用,同时不限制对来自同一模块的类的反射。但它不能完全取代安全管理器。

另外请记住,无论您做什么,仍然有人可能导致您的应用程序变得不稳定,尤其是当您允许任何类型的 I/O 或自己的线程时。但是插件仍然可以分配大量内存或只是运行无限循环 - 或者实际上只是同时运行两者;) 并且在 Java 中没有办法强制停止线程或限制某些代码分配的内存量。
我能看到的唯一部分解决方案是使用 java 代理来检测每个插件的代码,并添加调用来检查线程是否在任何可能运行时间过长的代码中被中断。
分配也是可能的。
但是您还需要 100% 确定白名单中的任何方法都不会循环或一次分配太多。

基本上:不要。

如果您可以稍微信任插件但您只想设置一些规则以避免不良做法,这只是一个好的解决方案(没有代理)。它不会阻止想要破坏某些东西的人,但会阻止典型的程序员创建不干净的代码。

如果您需要运行不受信任的代码...要么在操作系统级别的实际沙箱中运行它,例如查看 sphere engine 并仅以某种安全方式与其通信。
或者使用一些其他语言,让您可以执行与上述相同但更容易的操作,例如 Lua。 http://lua-users.org/wiki/SandBoxes 然后,您可以使用脚本引擎从 java 运行此类语言 https://github.com/luaj/luaj 但即便如此,也很难 100% 确定它会正常工作,并且没有人会发现和使用漏洞,因为如果攻击者需要的只是对 cpu/内存施加足够的压力以破坏主应用程序,那么这并不需要太多.

关于security - 如何构建一个安全的(受限生态系统)基于插件的架构(在 Kotlin 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60138600/

相关文章:

php - 如何可逆地随机化/加密从 0 到大约 0 的无符号整数。 2^24?

android - Kotlin异步任务/Firebase查询,等待结果的最佳方法?

security - Ubuntu 服务器上的沙箱

java - Java项目中的信任边界违规缺陷

使用委托(delegate)的 Kotlin 隐式覆盖

java - AlertDialog如何处理对话框 View 之外的点击

jquery - 有什么方法可以将类添加到 JOOMLA PLUGIN

java - 使用引用库在 Eclipse 中导出不可执行的 jar

plugins - 如何调用某些路由的Hapi插件?

swift - 如何手动清零内存?