作为Java动力游戏的一部分,我正在开发我计划嵌入Groovy(或可能是其他一些)脚本语言以允许较低级别的mod支持以及诸如对话和任务文件之类的事情在游戏世界中产生效果的方式。然而,我的目的和潜在的mod作者的目的可能会有所不同,如果可能的话,我想避免删除不危险的语言特征。在安全沙箱中,哪些Java类/包可以安全地列入白名单?
尽管我的具体需求当然会与公共规范有所不同,但我仍然很好奇,是否有任何普遍认同的白名单(尽管很短)的Java包和类,可以在不对用户造成重大风险的情况下访问。
作为Java动力游戏的一部分,我正在开发我计划嵌入Groovy(或可能是其他一些)脚本语言以允许较低级别的mod支持以及诸如对话和任务文件之类的事情在游戏世界中产生效果的方式。然而,我的目的和潜在的mod作者的目的可能会有所不同,如果可能的话,我想避免删除不危险的语言特征。在安全沙箱中,哪些Java类/包可以安全地列入白名单?
尽管我的具体需求当然会与公共规范有所不同,但我仍然很好奇,是否有任何普遍认同的白名单(尽管很短)的Java包和类,可以在不对用户造成重大风险的情况下访问。
我怀疑你会发现,不是从一个通用的编程语言开始,并想出如何让人们访问它并使其安全,而是以另一种方式更安全。
我的方法是从一个特定于领域的语言开始,让它访问一个沙箱 - 您愿意并乐意让模块影响您的程序环境的各个方面。
但是,我仍然好奇,是否有任何普遍认同的白名单(但是很短)的Java包和类,可以访问没有重大风险的用户。
是的,有白名单,但我不知道“一般同意”他们是如何。社区共识是审核白名单的一种方式,但您也可以查看列表创建者的经验,并查看他们的流程是否有意义。
乔-E项目想出了一个Java的“驯服”,并且该部分之一,是由类/方法/领域的核心库的白名单。例如,对于StringBuilder
,StringBuilder.safej说
# Manually verified.
class("java.lang.StringBuilder",
static(constructor("StringBuilder()"),
constructor("StringBuilder(CharSequence)"),
...
method(suppress, "insert(int, Object)", comment("calls toString on arbitrary object")),
# auto-generated safej: default deny everything
class("java.lang.Runtime",
static(method(suppress, "getRuntime()", comment("default deny")),
method(suppress, "runFinalizersOnExit(boolean)", comment("default deny"))),
...
要了解驯服,看到Joe-E paper它说:
4.2.1驯服的Java类库
Java库定义了许多对外界有影响的静态方法,以及许多创建允许类似效果的对象的构造函数 。这是Java中环境权威的主要来源。例如,文件 有一个构造函数,它将接收一个字符串并返回一个表示具有该名称的文件的对象 。结果对象 可用于读取,写入或删除指定文件。如果没有Java安全管理器或操作系统的显式访问控制,这允许任何Java代码完全控制文件系统。在Joe-E中,如果文件 (或超级目录)的功能位于该代码的动态范围内,我们希望确保 代码只能访问文件。
因此,我们不能在Joe-E的全局范围内允许上述File 构造函数。 我们定义了仅包含 兼容 的那些构造函数,方法和字段的Java库子集,其原理是必须通过 功能授予所有特权。我们将这种活动称为驯服,因为它会将不稳定的类库变成能力安全的子集。 JoeE验证程序允许Joe-E程序仅提及此驯服子集中的类, 构造函数,方法和字段。如果 源代码提到此子集以外的任何东西,则Joe-E验证者将此作为错误标识。
Taming有助于消除环境权限,因为它确保提供环境权限的库方法不是可供Joe-E程序访问的 。我们也使用驯服来公开仅提供能力训练的Java库的子集。
如果字节码静态分析可能会列出API列表,那将会很有趣。虽然很棘手。 /'文件'是一个有趣的。它应该表示一个文件路径字符串。所有有安全检查的方法都会带来危险。 (另外一个很大的危险是'File'实际上并不是不可变的, –
@ TomHawtin-tackline,一些静态流分析可以通过暴露缺失的源来帮助调试白名单,例如对待'new java.io.FileInputStream(String ,String)'作为接收器,并确保所有到达它的字符串都被白名单识别为系统资源。它永远不会是完整的,并且可能不会接近保守,因为存在java.lang .reflect.Method'和轻松制作[不透明谓词](http://en.wikipedia.org/wiki/Opaque_predicate)。 –
Java反射不会在白名单中。我不记得Joe-E是否这样做,但是一些对象能力语言支持通过invites进行反射(代码可以创建一个具有反射访问的对象,就好像它是创建它的代码一样 - 然后可以传递给更一般的码)。同样,任何使用反射的代码都很难列入白名单。即使是使用可变静态的代码(例如'private static final char []')也会带来很大的问题。 –
我会尝试模拟Java applet沙盒模型。如果沙箱足够安全,可以在我的PC上运行互联网上的任意代码,那么对于您的用户脚本来说,它应该足够安全。那么,你可能不希望用户脚本弹出一些GUI窗口,所以你需要比applet沙盒限制更多的权限。
用户脚本通常是由天真的开发人员撰写的,并且比引用它们的应用程序更少审阅,所以更容易[脚本注入]等[confused deputy](http://en.wikipedia.org/wiki/Confused_deputy_problem)漏洞核心代码库。 –
OP希望支持用户脚本,并想知道如何安全地执行操作。 – ZhongYu
同意。 OP是明智的尝试赋予用户脚本足够的权限以完成他们的工作,但由于脚本作者的天赋和较低的审查和测试标准,所以没有更多。 –
此代码是在(例如您的)服务器上运行还是在客户端计算机上运行? –
不完全一样,但这个问题可能也证明对你有用,如果你还没有发现它:http://stackoverflow.com/questions/6210045/bullet-proof-groovy-script-embedding –
@AndrewThompson代码将可以在客户端机器上运行,但是我担心的是,我最终希望添加多人游戏支持以及托管改装服务器的能力。在这种情况下,我正在研究允许这种(第三方)改装服务器直接向连接客户端提供所需的mod文件(可能包含脚本)的可行性。这当然需要成为一个“选择加入”的过程,但这不仅仅是一个安全问题。请参阅[这里](http://gamedev.stackexchange.com/questions/59390/how-far-should-i-go-in-securing-groovy-mod-scripts) – Hawkwing