Hi,
I am not an expert in JSR 223. However, some JSR 223 implementations
include a mechanism for restricting access to Java classes, for example
Nashorn [1] and Rhino [2], which might be sufficient for your needs.
(Note, Nashorn was deprecated and removed from JDK 15 [3]). I think most
of the permissions you list below can be mapped to a small list of Java
classes that check those permissions. Also, with strong encapsulation of
JDK internals enforced by default in JDK 17 [4], you get additional
protection that is not dependent on the Security Manager.
What JSR 223 implementation do you use?
--Sean
[1]
https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/api.html#classfilter_introduction
[2]
https://mozilla.github.io/rhino/javadoc/org/mozilla/javascript/ClassShutter.html
[3] https://openjdk.java.net/jeps/372
[4] https://openjdk.java.net/jeps/403
On 7/21/21 12:35 PM, Alexey Shponarsky wrote:
Hello,
At Jelastic PaaS, we are using SecurityManager within Java Scripting
(JSR 223). Specifically, Java Scripting allows us and our customers to
easily extend the core platform functionality with custom logic. The
developers can execute their custom scriptlets inside a Java Scripting
runtime environment with pre-injected core platform API methods. For
example,
//@req(pathFrom, pathTo)
varmountFrom = "${nodes.build.first.id <http://nodes.build.first.id/>}",
envName = "${settings.targetEnv}",
mountTo = "cp";
varresp = jelastic.env.file.RemoveMountPointByGroup(envName, session,
mountTo, pathTo);
if(resp.result != 0) returnresp;
returnjelastic.env.file.AddMountPointByGroup(envName, session,
mountTo, pathTo, 'nfs', null, pathFrom, mountFrom, '', false);
As Java Scripting engine / technology provides quite powerful
runtimes, we have to restrict certains actions such as execution of
any reflection methods, change of any system environment variables,
exit, calling some dangerous static methods, reading files outside of
the sandbox folder, etc. The SecurityManager mechanism provided an
ability to configure permissions easily.
To achieve this we create an instance of AccessControlContext with
required permissions and pass it to AccessController.doPrivileged
<https://docs.oracle.com/javase/8/docs/api/java/security/AccessController.html#doPrivileged-java.security.PrivilegedAction-java.security.AccessControlContext->method:
//Create list of Permission:
Collection<Permission> perms= new LinkedList<Permission>();
perms.add(new RuntimePermission("createClassLoader"));
perms.add(new RuntimePermission("getClassLoader"));
perms.add(new RuntimePermission("accessDeclaredMembers"));
perms.add(new RuntimePermission("getProtectionDomain"));
perms.add(new PropertyPermission("*", "read"));
perms.add(new SocketPermission("*", "connect,accept,resolve"));
perms.add(new SocketPermission("localhost:0-",
"connect,accept,resolve,listen"));
//Create AccessControlContext
ProtectionDomain domain = new ProtectionDomain(new CodeSource(null,
(Certificate[]) null), perms);
AccessControlContext acc= new AccessControlContext(new
ProtectionDomain[]{domain});
//Run untrusted code using created AccessControlContext
@Override
public ScriptEvalResponse call() throws Exception {
Object obj = AccessController.doPrivileged(new
PrivilegedAction<Object>() {
@Override
public Object run() {
try {
Object response = compiledScript.eval(ctx);
ScriptEvalResponse evalResponse = new ScriptEvalResponse(Response.OK);
evalResponse.setResponse(response);
return evalResponse;
} catch (Exception ex) {
logger.debug("Error occurred during eval script:", ex);
return ex;
}
}
}, acc);
if (obj instanceof Exception) {
throw (Exception) obj;
}
return (ScriptEvalResponse) obj;
}
How can we implement a similar solution after the removal of
SecurityManager? Could you help us to find an alternative?
--
Alexey Shponarsky Director of R&D
Twitter <https://twitter.com/Jelastic>Facebook
<https://www.facebook.com/Jelastic/>YouTube
<http://www.youtube.com/user/JelasticCloud>LinkedIn
<https://www.linkedin.com/company/2426564/>Google+
<https://plus.google.com/+JelasticInc>