[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 <github@schaus.net>pull/1821/head
parent
7cb746ece1
commit
4e045204ac
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue