Last active
December 30, 2015 08:39
-
-
Save purplefox/7804105 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import javax.script.*; | |
/* | |
This example demonstrates possible leakage of Nashorn scopes and the incorrect scope being used when executing | |
a function defined in one scope, from another scope. | |
*/ | |
public class LeakTest { | |
public static void main(String[] args) { | |
new LeakTest().run(); | |
} | |
/* | |
script1 contains a function which simply sets a global, and then immediately logs out the type of the global | |
to system.out | |
I would expect it to log "typeof global is number" | |
Instead it logs "typeof global is undefined" | |
script1 runs inside its own scope - this is basically how commonJS modules would be run -they are allowed to set | |
globals but these won't be visible to other scopes that call it. | |
*/ | |
private String script1 = | |
"function foo() { \n" + | |
" _someglobal = 123; \n" + | |
" java.lang.System.out.println('typeof global is ' + typeof _someglobal); \n" + | |
" // Now set another global \n" + | |
" _someotherglobal = 456; \n" + | |
"} \n" + | |
"_javaobject.setFunction(foo);"; | |
/* | |
script2 simply calls the function foo() which we export by setting its value through a Java object | |
it then tries to display the value of _someotherglobal which was defined in another scope, and succeeds! | |
*/ | |
private String script2 = | |
"foo(); \n" + | |
"java.lang.System.out.println('someotherglobal is ' + _someotherglobal)"; | |
private void run() { | |
try { | |
ScriptEngineManager factory = new ScriptEngineManager(); | |
ScriptEngine engine = factory.getEngineByName("nashorn"); | |
// Run script1 in it's own scope | |
ScriptContext ctx = new SimpleScriptContext(); | |
Bindings bindings = engine.createBindings(); | |
bindings.put("_javaobject", this); | |
ctx.setBindings(bindings, ScriptContext.ENGINE_SCOPE); | |
engine.eval(script1, ctx); | |
// Run script2 in it's own scope | |
bindings = engine.createBindings(); | |
bindings.put("foo", function); | |
ctx = new SimpleScriptContext(); | |
ctx.setBindings(bindings, ScriptContext.ENGINE_SCOPE); | |
engine.eval(script2, ctx); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
private Object function; | |
// This allows us to pass an JavaScript object from one scope to another | |
public void setFunction(Object function) { | |
this.function = function; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment