diff --git a/phoenicis-scripts/src/main/java/org/phoenicis/scripts/ScriptsConfiguration.java b/phoenicis-scripts/src/main/java/org/phoenicis/scripts/ScriptsConfiguration.java index 12c3b80b32d..e52c930858d 100644 --- a/phoenicis-scripts/src/main/java/org/phoenicis/scripts/ScriptsConfiguration.java +++ b/phoenicis-scripts/src/main/java/org/phoenicis/scripts/ScriptsConfiguration.java @@ -21,6 +21,7 @@ import org.phoenicis.multithreading.MultithreadingConfiguration; import org.phoenicis.repository.RepositoryConfiguration; import org.phoenicis.scripts.engine.PhoenicisScriptEngineFactory; +import org.phoenicis.scripts.engine.implementation.PhoenicisSandbox; import org.phoenicis.scripts.interpreter.PhoenicisScriptInterpreter; import org.phoenicis.scripts.engine.ScriptEngineType; import org.phoenicis.scripts.engine.injectors.*; @@ -51,18 +52,27 @@ public class ScriptsConfiguration { @Autowired private MultithreadingConfiguration multithreadingConfiguration; + @Bean + public PhoenicisSandbox phoenicisSandbox() { + return new PhoenicisSandbox(); + } + @Bean public PhoenicisScriptEngineFactory graalScriptEngineFactory() { - return new PhoenicisScriptEngineFactory(ScriptEngineType.GRAAL, Arrays.asList(new ScriptUtilitiesInjector(), - new BeanInjector(applicationContext), new SetupWizardInjector(wizardConfiguration.setupWizardFactory()), - new IncludeInjector(scriptFetcher()), new LocalisationInjector())); + return new PhoenicisScriptEngineFactory(phoenicisSandbox(), ScriptEngineType.GRAAL, + Arrays.asList(new ScriptUtilitiesInjector(), + new BeanInjector(applicationContext), + new SetupWizardInjector(wizardConfiguration.setupWizardFactory()), + new IncludeInjector(scriptFetcher()), new LocalisationInjector())); } @Bean public PhoenicisScriptEngineFactory nashornScriptEngineFactory() { - return new PhoenicisScriptEngineFactory(ScriptEngineType.NASHORN, Arrays.asList(new ScriptUtilitiesInjector(), - new BeanInjector(applicationContext), new SetupWizardInjector(wizardConfiguration.setupWizardFactory()), - new IncludeInjector(scriptFetcher()), new LocalisationInjector())); + return new PhoenicisScriptEngineFactory(phoenicisSandbox(), ScriptEngineType.NASHORN, + Arrays.asList(new ScriptUtilitiesInjector(), + new BeanInjector(applicationContext), + new SetupWizardInjector(wizardConfiguration.setupWizardFactory()), + new IncludeInjector(scriptFetcher()), new LocalisationInjector())); } @Bean diff --git a/phoenicis-scripts/src/main/java/org/phoenicis/scripts/engine/PhoenicisScriptEngineFactory.java b/phoenicis-scripts/src/main/java/org/phoenicis/scripts/engine/PhoenicisScriptEngineFactory.java index 79c8b9952d4..d1e550fc16b 100644 --- a/phoenicis-scripts/src/main/java/org/phoenicis/scripts/engine/PhoenicisScriptEngineFactory.java +++ b/phoenicis-scripts/src/main/java/org/phoenicis/scripts/engine/PhoenicisScriptEngineFactory.java @@ -18,6 +18,7 @@ package org.phoenicis.scripts.engine; +import org.phoenicis.scripts.engine.implementation.PhoenicisSandbox; import org.phoenicis.scripts.engine.injectors.EngineInjector; import org.phoenicis.scripts.engine.implementation.PhoenicisScriptEngine; @@ -25,15 +26,18 @@ public class PhoenicisScriptEngineFactory { private final ScriptEngineType type; + private final PhoenicisSandbox phoenicisSandbox; private final List engineInjectors; - public PhoenicisScriptEngineFactory(ScriptEngineType type, List engineInjectors) { + public PhoenicisScriptEngineFactory(PhoenicisSandbox phoenicisSandbox, ScriptEngineType type, + List engineInjectors) { this.type = type; this.engineInjectors = engineInjectors; + this.phoenicisSandbox = phoenicisSandbox; } public PhoenicisScriptEngine createEngine() { - final PhoenicisScriptEngine phoenicisScriptEngine = type.createScriptEngine(); + final PhoenicisScriptEngine phoenicisScriptEngine = type.createScriptEngine(this.phoenicisSandbox); engineInjectors.forEach(engineInjector -> engineInjector.injectInto(phoenicisScriptEngine)); diff --git a/phoenicis-scripts/src/main/java/org/phoenicis/scripts/engine/ScriptEngineType.java b/phoenicis-scripts/src/main/java/org/phoenicis/scripts/engine/ScriptEngineType.java index 9918026c777..5162b6a323a 100644 --- a/phoenicis-scripts/src/main/java/org/phoenicis/scripts/engine/ScriptEngineType.java +++ b/phoenicis-scripts/src/main/java/org/phoenicis/scripts/engine/ScriptEngineType.java @@ -1,6 +1,7 @@ package org.phoenicis.scripts.engine; import org.phoenicis.scripts.engine.implementation.JSAScriptEngine; +import org.phoenicis.scripts.engine.implementation.PhoenicisSandbox; import org.phoenicis.scripts.engine.implementation.PhoenicisScriptEngine; import org.phoenicis.scripts.engine.implementation.PolyglotScriptEngine; @@ -12,15 +13,15 @@ public enum ScriptEngineType { NASHORN("nashorn") { @Override - public PhoenicisScriptEngine createScriptEngine() { + public PhoenicisScriptEngine createScriptEngine(PhoenicisSandbox sandbox) { return new JSAScriptEngine("nashorn"); } }, GRAAL("graal.js") { @Override - public PhoenicisScriptEngine createScriptEngine() { - return new PolyglotScriptEngine("js", Map.of("js.nashorn-compat", "true")); + public PhoenicisScriptEngine createScriptEngine(PhoenicisSandbox sandbox) { + return new PolyglotScriptEngine(sandbox, "js", Map.of("js.nashorn-compat", "true")); } }; @@ -43,7 +44,7 @@ public PhoenicisScriptEngine createScriptEngine() { * * @return The new instance of the {@link ScriptEngineType} */ - public abstract PhoenicisScriptEngine createScriptEngine(); + public abstract PhoenicisScriptEngine createScriptEngine(PhoenicisSandbox phoenicisSandbox); @Override public String toString() { diff --git a/phoenicis-scripts/src/main/java/org/phoenicis/scripts/engine/implementation/PhoenicisSandbox.java b/phoenicis-scripts/src/main/java/org/phoenicis/scripts/engine/implementation/PhoenicisSandbox.java new file mode 100644 index 00000000000..ae1dc5f1575 --- /dev/null +++ b/phoenicis-scripts/src/main/java/org/phoenicis/scripts/engine/implementation/PhoenicisSandbox.java @@ -0,0 +1,33 @@ +package org.phoenicis.scripts.engine.implementation; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Filters classes that are allowed to be used inside scripts + */ +public class PhoenicisSandbox { + private static final Logger LOGGER = LoggerFactory.getLogger(PhoenicisSandbox.class); + + public boolean isSafe(String identifier) { + LOGGER.debug("Loading {} in javascript context", identifier); + if (identifier.startsWith("org.phoenicis")) { + return true; + } + + if (identifier.startsWith("java.lang")) { + // FIXME: This should be more fine-tuned later + // Contains process builder + return true; + } + + if (identifier.startsWith("java.util")) { + // FIXME: This should be more fine-tuned later + return true; + } + + // Needed by GraalVM + return identifier.startsWith("java.net.URLClassLoader"); + + } +} diff --git a/phoenicis-scripts/src/main/java/org/phoenicis/scripts/engine/implementation/PolyglotScriptEngine.java b/phoenicis-scripts/src/main/java/org/phoenicis/scripts/engine/implementation/PolyglotScriptEngine.java index 69406983fca..3d144bfd220 100644 --- a/phoenicis-scripts/src/main/java/org/phoenicis/scripts/engine/implementation/PolyglotScriptEngine.java +++ b/phoenicis-scripts/src/main/java/org/phoenicis/scripts/engine/implementation/PolyglotScriptEngine.java @@ -33,16 +33,18 @@ public class PolyglotScriptEngine implements PhoenicisScriptEngine { /** * Constructor * + * @param phoenicisSandbox a Phoenicis Sandbox bean * @param language The language name * @param options A map of options for the Polyglot context */ - public PolyglotScriptEngine(String language, Map options) { + public PolyglotScriptEngine(PhoenicisSandbox phoenicisSandbox, String language, Map options) { super(); this.errorHandlers = new ArrayList<>(); this.language = language; this.context = Context.newBuilder(language) .allowExperimentalOptions(true) + .allowHostClassLookup(phoenicisSandbox::isSafe) .options(options).allowHostAccess(true).build(); } diff --git a/phoenicis-scripts/src/main/java/org/phoenicis/scripts/ui/InstallationType.java b/phoenicis-scripts/src/main/java/org/phoenicis/scripts/ui/InstallationType.java index 9459a116c33..874d41094dc 100644 --- a/phoenicis-scripts/src/main/java/org/phoenicis/scripts/ui/InstallationType.java +++ b/phoenicis-scripts/src/main/java/org/phoenicis/scripts/ui/InstallationType.java @@ -1,8 +1,11 @@ package org.phoenicis.scripts.ui; +import org.phoenicis.configuration.security.Safe; + /** * type of the installation */ +@Safe public enum InstallationType { APPS("Apps"), ENGINES("Engines"), VERBS("Verbs");