A secure sandbox for executing JavaScript in Java apps using the Graal JS engine.
Also see Nashorn Sandbox and Rhino Sandbox.
Part of the Java Delight Suite.
The sandbox by default blocks access to all Java classes.
Classes, which should be used in JavaScript, must be explicitly allowed.
GraalSandbox sandbox = GraalSandboxes.create();
sandbox.allow(File.class);
sandbox.eval("var File = Java.type('java.io.File'); File;")
Or you can inject your Java object as a JS global variable
GraalSandboxes sandbox = GraalSandboxes.create();
sandbox.inject("fromJava", new Object());
sandbox.eval("fromJava.getClass();");
The sandbox also allows limiting the CPU time and memory usage of scripts. This allows terminating scripts which contain infinite loops and other problematic code.
GraalSandbox sandbox = GraalSandboxes.create();
sandbox.setMaxCPUTime(100);
sandbox.setMaxMemory(500*1024);
sandbox.allowNoBraces(false);
sandbox.setMaxPreparedStatements(30); // because preparing scripts for execution is expensive
sandbox.setExecutor(Executors.newSingleThreadExecutor());
sandbox.eval("var o={}, i=0; while (true) {o[i++]='abc';};");
This code will raise a ScriptCPUAbuseException.
The sandbox beautifies the JavaScript code for this and injects additional statements into the submitted code. It is thus possible that the original line numbers from the submitted JS code are not preserved. To debug the code, which is generated by the sandbox, activate its debug mode as follows using log4j.properties file:
log4j.logger.delight.graaljssandbox.internal.GraalSandboxImpl=DEBUG
This will output the generated JS on the console as follows:
--- Running JS ---
var \__it = Java.type('delight.graaljssandbox.internal.InterruptTest');var \__if=function(){\__it.test();};
while(true) {__if();
i = i+1;
}
--- JS END ---
Just add the following dependency to your projects.
<dependency>
<groupId>org.javadelight</groupId>
<artifactId>delight-graaljs-sandbox</artifactId>
<version>[insert latest version]</version>
</dependency>
This artifact is available on Maven Central and BinTray.
This project is based on a PR in the Nashorn Sandbox project by Marco Ellwanger. The Graal JS sandbox has been extracted from the Nashorn Sandbox repository to provide projects with a dedicated module to use if Graal JS sandbox capabilities are required.
Marco Ellwanger: Initial support for GraalJS engine by implementing sandbox implementation backed by GraalJS.
- 0.1.2: Allowing access to Java classes (PR 2 by JavaGrinko)
- 0.1.1: Update to latest Graal JS and Nashorn Sandbox dependency (PR 1 by thmarx)
- 0.1.0: Initial support for Graal JS (Nashorn PR #87 by mellster2012)