From 4e045204acfda6c53055bc25db52e831d337fc55 Mon Sep 17 00:00:00 2001 From: Yannick Schaus Date: Sat, 14 Nov 2020 15:17:33 +0100 Subject: [PATCH] [automation] Create Nashorn script engines with the proper class loader (#1799) This should fix the issue reported here: https://community.openhab.org/t/openhab-3-0-milestone-2-discussion/107564/8 where the Nashorn script engine would be created with the current thread's class loader, causing JS code like this: ``` var Log = Java.type("org.openhab.core.model.script.actions.Log"); Log.logError("Experiments", "This is an OH error log"); Log.logWarn("Experiments", "This is an OH warn log"); Log.logInfo("Experiments", "This is an OH info log"); Log.logDebug("Experiments", "This is an OH debug log"); ``` to run fine when the rule was triggered but fail to find the Log class when run from the REST API's `/rest/rules/{ruleUID}/runnow`, because in that case the generic createScriptEngine implementation would return script engines using the JAX-RS class loader as the "app" class loader. Note: We also have an opportunity to restrict which classes are exposed to the script with a ClassFilter to a specific set: https://docs.oracle.com/javase/8/docs/jdk/api/nashorn/jdk/nashorn/api/scripting/NashornScriptEngineFactory.html#getScriptEngine-java.lang.String:A-java.lang.ClassLoader-jdk.nashorn.api.scripting.ClassFilter- This could prove useful to mitigate code execution vulnerabilities, as the script code is modifiable remotely. Signed-off-by: Yannick Schaus --- .../script/internal/NashornScriptEngineFactory.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/NashornScriptEngineFactory.java b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/NashornScriptEngineFactory.java index cd10f7f66a..2c709e6c8c 100644 --- a/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/NashornScriptEngineFactory.java +++ b/bundles/org.openhab.core.automation.module.script/src/main/java/org/openhab/core/automation/module/script/internal/NashornScriptEngineFactory.java @@ -24,6 +24,7 @@ import javax.script.ScriptEngine; import javax.script.ScriptException; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; import org.openhab.core.automation.module.script.AbstractScriptEngineFactory; import org.openhab.core.automation.module.script.ScriptEngineFactory; import org.osgi.service.component.annotations.Component; @@ -33,6 +34,7 @@ import org.osgi.service.component.annotations.Component; * * @author Simon Merschjohann - Initial contribution * @author Scott Rushworth - removed default methods provided by ScriptEngineFactory + * @author Yannick Schaus - create script engines with the bundle's class loader as "app" class loader */ @NonNullByDefault @Component(service = ScriptEngineFactory.class) @@ -72,4 +74,13 @@ public class NashornScriptEngineFactory extends AbstractScriptEngineFactory { logger.error("ScriptException while importing scope: {}", ex.getMessage()); } } + + @Override + public @Nullable ScriptEngine createScriptEngine(String scriptType) { + ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(NashornScriptEngineFactory.class.getClassLoader()); + ScriptEngine scriptEngine = super.createScriptEngine(scriptType); + Thread.currentThread().setContextClassLoader(originalClassLoader); + return scriptEngine; + } }