我们的Java应用程序的一部分需要运行由非开发人员编写的javascript.这些非开发人员使用javascript进行数据格式化.(主要是简单的逻辑和字符串连接).
我的问题是如何设置这些脚本的执行以确保脚本错误不会对应用程序的其余部分产生重大负面影响.
需要防范无限循环
防止产生新线程.
限制对服务和环境的访问
文件系统(示例:如果心怀不满的脚本编写者决定删除文件)
数据库(同样删除数据库记录)
基本上我需要设置javascript范围,只包括他们需要的内容,而不是更多内容.
为了防止无限循环,您可以在脚本运行时观察指令计数(这仅适用于已解释的脚本,而不适用于已编译的脚本).
有此例中的犀牛的JavaDoc以防止脚本从十几秒钟运行:
protected void observeInstructionCount(Context cx, int instructionCount) { MyContext mcx = (MyContext)cx; long currentTime = System.currentTimeMillis(); if (currentTime - mcx.startTime > 10*1000) { // More then 10 seconds from Context creation time: // it is time to stop the script. // Throw Error instance to ensure that script will never // get control back through catch or finally. throw new Error(); } }
要阻止Java类和方法访问,请看...
http://codeutopia.net/blog/2009/01/02/sandboxing-rhino-in-java/
为了防止无限循环,你需要将它放在一个单独的进程中,以便它可以被杀死.
为了防止创建线程,您需要扩展SecurityManager(默认实现允许不受信任的代码访问非根线程组).
Java安全性允许您阻止对文件系统的访问.
对于数据库限制,您可能能够使用标准SQL用户安全性,但这非常弱.否则,您需要提供一个强制执行限制的API.
编辑:我应该指出,JDK6提供的Rhino版本已经完成了安全工作,但不包括编译器.