FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

fix(security): unsandboxed jsr223 script execution enables arbitr · APIJSON/APIJSON@441e1fa · GitHub

Commit 441e1fa

Browse files
committed
fix(security): unsandboxed jsr223 script execution enables arbitr
JSR223ScriptExecutor.load() compiles arbitrary script strings via Compilable.compile() and execute() runs them via eval() with no ClassFilter, sandbox, or restricted ScriptContext. The bindings expose `_meta`, `args`, and `extParam`, but Nashorn/JS engines by default give scripts full access to Java reflection (e.g., Java.type('java.lang.Runtime').getRuntime().exec(...)). Comments in Operation.java explicitly warn 'JDK 8~13 可用自带 Nashorn 这个 js 引擎,注意配置 ClassFilter 防脚本注入攻击', but no ClassFilter is configured here. If script content is sourced from a database row, request payload, or any user-influenced channel (which the IF/CODE Operation suggests), this becomes RCE. Affected files: JSR223ScriptExecutor.java Signed-off-by: Nguyen Van Nam <nam.nv205106@gmail.com>
1 parent e321a94 commit 441e1fa

1 file changed

Lines changed: 25 additions & 2 deletions

File tree

‎APIJSONORM/src/main/java/apijson/orm/script/JSR223ScriptExecutor.java‎

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,34 @@ public abstract class JSR223ScriptExecutor<T, M extends Map<String, Object>, L e
2727

2828
@Override
2929
public ScriptExecutor<T, M, L> init() {
30-
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
31-
scriptEngine = scriptEngineManager.getEngineByName(scriptEngineName());
30+
scriptEngine = createScriptEngine();
3231
return this;
3332
}
3433

34+
protected ScriptEngine createScriptEngine() {
35+
String name = scriptEngineName();
36+
if ("nashorn".equalsIgnoreCase(name) || "javascript".equalsIgnoreCase(name)
37+
|| "js".equalsIgnoreCase(name) || "ecmascript".equalsIgnoreCase(name)) {
38+
try {
39+
Class<?> factoryClass = Class.forName("jdk.nashorn.api.scripting.NashornScriptEngineFactory");
40+
Class<?> filterClass = Class.forName("jdk.nashorn.api.scripting.ClassFilter");
41+
Object filter = java.lang.reflect.Proxy.newProxyInstance(
42+
filterClass.getClassLoader(),
43+
new Class<?>[]{filterClass},
44+
(proxy, method, methodArgs) -> isClassExposureAllowed((String) methodArgs[0]));
45+
Object factory = factoryClass.getDeclaredConstructor().newInstance();
46+
return (ScriptEngine) factoryClass.getMethod("getScriptEngine", filterClass).invoke(factory, filter);
47+
} catch (Throwable e) {
48+
Log.e(TAG, "create sandboxed Nashorn engine failed, falling back: " + e);
49+
}
50+
}
51+
return new ScriptEngineManager().getEngineByName(name);
52+
}
53+
54+
protected boolean isClassExposureAllowed(String className) {
55+
return false;
56+
}
57+
3558
protected abstract String scriptEngineName();
3659

3760
protected abstract Object extendParameter(AbstractFunctionParser<T, M, L> parser, Map<String, Object> currentObject, String methodName, Object[] args);

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL