The one fixes a minor bug and adds support for code from Readers and support for compiled scripts:
import groovy.util.GroovyScriptEngine;
import java.io.Reader;
import java.io.StringReader;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.Permission;
import java.security.Permissions;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.util.Collection;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class ScriptSandbox {
ScriptEngine _scriptEngine;
AccessControlContext _accessControlContext;
public ScriptSandbox(String engineShortName) throws InstantiationException{
ScriptEngineManager sem = new ScriptEngineManager();
_scriptEngine = sem.getEngineByName(engineShortName);
if (_scriptEngine==null){
throw new InstantiationException("Could not load script engine: "+
engineShortName);
}
setPermissions(null);
}
public boolean isCompilable(){
return _scriptEngine instanceof Compilable;
}
public void setPermissions(Collection<Permission> permissionCollection){
Permissions perms = new Permissions();
perms.add(new RuntimePermission("accessDeclaredMembers"));
if (permissionCollection!=null){
for (Permission p : permissionCollection){
perms.add(p);
}
}
// Cast to Certificate[] required because of ambiguity:
ProtectionDomain domain = new ProtectionDomain(
new CodeSource( null, (Certificate[]) null ), perms );
_accessControlContext = new AccessControlContext(
new ProtectionDomain[] { domain } );
}
public Object eval(String code){
return eval(new StringReader(code));
}
public Object eval(final Reader rdr){
return AccessController.doPrivileged(new PrivilegedAction(){
@Override
public Object run() {
try {
return _scriptEngine.eval(rdr);
} catch (ScriptException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}}, _accessControlContext);
}
public CompiledScript compile(String str) throws ScriptException{
return ((Compilable)_scriptEngine).compile(str);
}
public CompiledScript compile(Reader rdr) throws ScriptException{
return ((Compilable)_scriptEngine).compile(rdr);
}
public Object execute(final CompiledScript script){
return AccessController.doPrivileged(new PrivilegedAction(){
@Override
public Object run() {
try {
return script.eval();
} catch (ScriptException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}}, _accessControlContext);
}
}
import groovy.util.GroovyScriptEngine;
import java.io.Reader;
import java.io.StringReader;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.Permission;
import java.security.Permissions;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.util.Collection;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class ScriptSandbox {
ScriptEngine _scriptEngine;
AccessControlContext _accessControlContext;
public ScriptSandbox(String engineShortName) throws InstantiationException{
ScriptEngineManager sem = new ScriptEngineManager();
_scriptEngine = sem.getEngineByName(engineShortName);
if (_scriptEngine==null){
throw new InstantiationException("Could not load script engine: "+
engineShortName);
}
setPermissions(null);
}
public boolean isCompilable(){
return _scriptEngine instanceof Compilable;
}
public void setPermissions(Collection<Permission> permissionCollection){
Permissions perms = new Permissions();
perms.add(new RuntimePermission("accessDeclaredMembers"));
if (permissionCollection!=null){
for (Permission p : permissionCollection){
perms.add(p);
}
}
// Cast to Certificate[] required because of ambiguity:
ProtectionDomain domain = new ProtectionDomain(
new CodeSource( null, (Certificate[]) null ), perms );
_accessControlContext = new AccessControlContext(
new ProtectionDomain[] { domain } );
}
public Object eval(String code){
return eval(new StringReader(code));
}
public Object eval(final Reader rdr){
return AccessController.doPrivileged(new PrivilegedAction(){
@Override
public Object run() {
try {
return _scriptEngine.eval(rdr);
} catch (ScriptException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}}, _accessControlContext);
}
public CompiledScript compile(String str) throws ScriptException{
return ((Compilable)_scriptEngine).compile(str);
}
public CompiledScript compile(Reader rdr) throws ScriptException{
return ((Compilable)_scriptEngine).compile(rdr);
}
public Object execute(final CompiledScript script){
return AccessController.doPrivileged(new PrivilegedAction(){
@Override
public Object run() {
try {
return script.eval();
} catch (ScriptException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}}, _accessControlContext);
}
}
I really love this post.
ReplyDeleteMay you send me a sample code to call this sandbox as I don't know what permissions to allow for the untrusted code.
If your client is open source, I would love to see the code.
mail me at: mostafa.eweda17@gmail.com
THAAAAAAAAAAAAANKS