mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-03-25 09:28:27 +00:00
Remove vestiges of script engine sandboxing
This removes all the mentions of the sandbox from the script engine services and permissions model. This means that the following settings are no longer supported: ```yaml script.inline: sandbox script.stored: sandbox ``` Instead, only a `true` or `false` value can be specified. Since this would otherwise break the default-allow parameter for languages like expressions, painless, and mustache, all script engines have been updated to have individual settings, for instance: ```yaml script.engine.groovy.inline: true ``` Would enable all inline scripts for groovy. (they can still be overridden on a per-operation basis). Expressions, Painless, and Mustache all default to `true` for inline, file, and stored scripts to preserve the old scripting behavior. Resolves #17114
This commit is contained in:
parent
520697eb14
commit
a4060f7436
@ -60,11 +60,6 @@ public class NativeScriptEngineService extends AbstractComponent implements Scri
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSandboxed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String script, Map<String, String> params) {
|
||||
NativeScriptFactory scriptFactory = scripts.get(script);
|
||||
|
@ -29,11 +29,13 @@ public class ScriptEngineRegistry {
|
||||
|
||||
private final Map<Class<? extends ScriptEngineService>, List<String>> registeredScriptEngineServices;
|
||||
private final Map<String, Class<? extends ScriptEngineService>> registeredLanguages;
|
||||
private final Map<String, ScriptMode> defaultInlineScriptModes;
|
||||
|
||||
public ScriptEngineRegistry(Iterable<ScriptEngineRegistration> registrations) {
|
||||
Objects.requireNonNull(registrations);
|
||||
Map<Class<? extends ScriptEngineService>, List<String>> registeredScriptEngineServices = new HashMap<>();
|
||||
Map<String, Class<? extends ScriptEngineService>> registeredLanguages = new HashMap<>();
|
||||
Map<String, ScriptMode> inlineScriptModes = new HashMap<>();
|
||||
for (ScriptEngineRegistration registration : registrations) {
|
||||
List<String> languages =
|
||||
registeredScriptEngineServices.putIfAbsent(registration.getScriptEngineService(), Collections.unmodifiableList(registration.getScriptEngineLanguages()));
|
||||
@ -47,11 +49,13 @@ public class ScriptEngineRegistry {
|
||||
if (scriptEngineServiceClazz != null) {
|
||||
throw new IllegalArgumentException("scripting language [" + language + "] already registered for script engine service [" + scriptEngineServiceClazz.getCanonicalName() + "]");
|
||||
}
|
||||
inlineScriptModes.put(language, registration.getDefaultInlineScriptMode());
|
||||
}
|
||||
}
|
||||
|
||||
this.registeredScriptEngineServices = Collections.unmodifiableMap(registeredScriptEngineServices);
|
||||
this.registeredLanguages = Collections.unmodifiableMap(registeredLanguages);
|
||||
this.defaultInlineScriptModes = Collections.unmodifiableMap(inlineScriptModes);
|
||||
}
|
||||
|
||||
Iterable<Class<? extends ScriptEngineService>> getRegisteredScriptEngineServices() {
|
||||
@ -67,11 +71,22 @@ public class ScriptEngineRegistry {
|
||||
return registeredLanguages;
|
||||
}
|
||||
|
||||
Map<String, ScriptMode> getDefaultInlineScriptModes() {
|
||||
return this.defaultInlineScriptModes;
|
||||
}
|
||||
|
||||
public static class ScriptEngineRegistration {
|
||||
private final Class<? extends ScriptEngineService> scriptEngineService;
|
||||
private final List<String> scriptEngineLanguages;
|
||||
private final ScriptMode defaultInlineScriptMode;
|
||||
|
||||
public ScriptEngineRegistration(Class<? extends ScriptEngineService> scriptEngineService, List<String> scriptEngineLanguages) {
|
||||
// Default to "off/disabled" if not specified
|
||||
this(scriptEngineService, scriptEngineLanguages, ScriptMode.OFF);
|
||||
}
|
||||
|
||||
public ScriptEngineRegistration(Class<? extends ScriptEngineService> scriptEngineService, List<String> scriptEngineLanguages,
|
||||
ScriptMode defaultInlineScriptMode) {
|
||||
Objects.requireNonNull(scriptEngineService);
|
||||
Objects.requireNonNull(scriptEngineLanguages);
|
||||
if (scriptEngineLanguages.isEmpty()) {
|
||||
@ -79,6 +94,7 @@ public class ScriptEngineRegistry {
|
||||
}
|
||||
this.scriptEngineService = scriptEngineService;
|
||||
this.scriptEngineLanguages = scriptEngineLanguages;
|
||||
this.defaultInlineScriptMode = defaultInlineScriptMode;
|
||||
}
|
||||
|
||||
Class<? extends ScriptEngineService> getScriptEngineService() {
|
||||
@ -88,6 +104,10 @@ public class ScriptEngineRegistry {
|
||||
List<String> getScriptEngineLanguages() {
|
||||
return scriptEngineLanguages;
|
||||
}
|
||||
|
||||
ScriptMode getDefaultInlineScriptMode() {
|
||||
return defaultInlineScriptMode;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -35,8 +35,6 @@ public interface ScriptEngineService extends Closeable {
|
||||
|
||||
List<String> getExtensions();
|
||||
|
||||
boolean isSandboxed();
|
||||
|
||||
Object compile(String script, Map<String, String> params);
|
||||
|
||||
ExecutableScript executable(CompiledScript compiledScript, @Nullable Map<String, Object> vars);
|
||||
|
@ -24,13 +24,11 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* Mode for a specific script, used for script settings.
|
||||
* Defines whether a certain script or category of scripts can be executed or not, or whether it can
|
||||
* only be executed by a sandboxed scripting language.
|
||||
* Defines whether a certain script or category of scripts can be executed or not.
|
||||
*/
|
||||
enum ScriptMode {
|
||||
public enum ScriptMode {
|
||||
ON("true"),
|
||||
OFF("false"),
|
||||
SANDBOX("sandbox");
|
||||
OFF("false");
|
||||
|
||||
private final String mode;
|
||||
|
||||
|
@ -54,7 +54,7 @@ public class ScriptModes {
|
||||
* @param lang the language that the script is written in
|
||||
* @param scriptType the type of the script
|
||||
* @param scriptContext the operation that requires the execution of the script
|
||||
* @return whether scripts are on, off, or enabled only for sandboxed languages
|
||||
* @return whether scripts are on or off
|
||||
*/
|
||||
public ScriptMode getScriptMode(String lang, ScriptType scriptType, ScriptContext scriptContext) {
|
||||
//native scripts are always on as they are static by definition
|
||||
@ -76,6 +76,10 @@ public class ScriptModes {
|
||||
return SCRIPT_SETTINGS_PREFIX + "." + scriptType.getScriptType();
|
||||
}
|
||||
|
||||
static String getGlobalKey(String lang, ScriptType scriptType) {
|
||||
return ENGINE_SETTINGS_PREFIX + "." + lang + "." + scriptType;
|
||||
}
|
||||
|
||||
static String getKey(String lang, ScriptType scriptType, ScriptContext scriptContext) {
|
||||
return ENGINE_SETTINGS_PREFIX + "." + lang + "." + scriptType + "." + scriptContext.getKey();
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import org.elasticsearch.common.inject.multibindings.MapBinder;
|
||||
import org.elasticsearch.common.inject.multibindings.Multibinder;
|
||||
import org.elasticsearch.common.settings.Setting;
|
||||
import org.elasticsearch.common.settings.SettingsModule;
|
||||
import org.elasticsearch.script.ScriptMode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@ -40,7 +41,8 @@ public class ScriptModule extends AbstractModule {
|
||||
private final List<ScriptEngineRegistry.ScriptEngineRegistration> scriptEngineRegistrations = new ArrayList<>();
|
||||
|
||||
{
|
||||
scriptEngineRegistrations.add(new ScriptEngineRegistry.ScriptEngineRegistration(NativeScriptEngineService.class, NativeScriptEngineService.TYPES));
|
||||
scriptEngineRegistrations.add(new ScriptEngineRegistry.ScriptEngineRegistration(NativeScriptEngineService.class,
|
||||
NativeScriptEngineService.TYPES, ScriptMode.ON));
|
||||
}
|
||||
|
||||
private final Map<String, Class<? extends NativeScriptFactory>> scripts = new HashMap<>();
|
||||
|
@ -31,6 +31,7 @@ import org.elasticsearch.cluster.AckedClusterStateUpdateTask;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.cluster.service.ClusterService;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.ParseFieldMatcher;
|
||||
import org.elasticsearch.common.Strings;
|
||||
@ -478,8 +479,6 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
||||
return true;
|
||||
case OFF:
|
||||
return false;
|
||||
case SANDBOX:
|
||||
return scriptEngineService.isSandboxed();
|
||||
default:
|
||||
throw new IllegalArgumentException("script mode [" + mode + "] not supported");
|
||||
}
|
||||
@ -607,8 +606,8 @@ public class ScriptService extends AbstractComponent implements Closeable {
|
||||
*/
|
||||
public enum ScriptType {
|
||||
|
||||
INLINE(0, "inline", "inline", ScriptMode.SANDBOX),
|
||||
STORED(1, "id", "stored", ScriptMode.SANDBOX),
|
||||
INLINE(0, "inline", "inline", ScriptMode.OFF),
|
||||
STORED(1, "id", "stored", ScriptMode.OFF),
|
||||
FILE(2, "file", "file", ScriptMode.ON);
|
||||
|
||||
private final int val;
|
||||
|
@ -23,6 +23,7 @@ import org.elasticsearch.common.collect.Tuple;
|
||||
import org.elasticsearch.common.settings.Setting;
|
||||
import org.elasticsearch.common.settings.Setting.Property;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -96,7 +97,18 @@ public class ScriptSettings {
|
||||
// native scripts are always enabled, and their settings can not be changed
|
||||
continue;
|
||||
}
|
||||
for (ScriptService.ScriptType scriptType : ScriptService.ScriptType.values()) {
|
||||
ScriptMode defaultNonFileScriptMode = scriptEngineRegistry.getDefaultInlineScriptModes().get(language);
|
||||
for (final ScriptService.ScriptType scriptType : ScriptService.ScriptType.values()) {
|
||||
// This will be easier once ScriptMode is transitioned to booleans
|
||||
if (scriptType.getDefaultScriptMode() == ScriptMode.ON) {
|
||||
defaultNonFileScriptMode = ScriptMode.ON;
|
||||
}
|
||||
final ScriptMode defaultScriptMode = defaultNonFileScriptMode;
|
||||
// Like "script.engine.groovy.inline"
|
||||
final Setting<ScriptMode> langGlobalSetting = new Setting<>(ScriptModes.getGlobalKey(language, scriptType),
|
||||
defaultScriptMode.toString(), ScriptMode::parse, Property.NodeScope);
|
||||
scriptModeSettings.add(langGlobalSetting);
|
||||
|
||||
for (ScriptContext scriptContext : scriptContextRegistry.scriptContexts()) {
|
||||
Function<Settings, String> defaultSetting = settings -> {
|
||||
// fallback logic for script mode settings
|
||||
@ -116,6 +128,11 @@ public class ScriptSettings {
|
||||
return languageSettings.keySet().iterator().next();
|
||||
}
|
||||
|
||||
// the next fallback is settings configured for this engine and script type
|
||||
if (langGlobalSetting.exists(settings)) {
|
||||
return langGlobalSetting.get(settings).getMode();
|
||||
}
|
||||
|
||||
// the next fallback is global operation-based settings (e.g., "script.aggs: false")
|
||||
Setting<ScriptMode> setting = scriptContextSettingMap.get(scriptContext);
|
||||
if (setting.exists(settings)) {
|
||||
@ -129,7 +146,7 @@ public class ScriptSettings {
|
||||
}
|
||||
|
||||
// the final fallback is the default for the type
|
||||
return scriptType.getDefaultScriptMode().toString();
|
||||
return defaultScriptMode.toString();
|
||||
};
|
||||
Setting<ScriptMode> setting =
|
||||
new Setting<>(
|
||||
|
@ -22,6 +22,7 @@ package org.elasticsearch.index.query;
|
||||
import com.carrotsearch.randomizedtesting.generators.CodepointSetGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.core.io.JsonStringEncoder;
|
||||
import org.elasticsearch.script.ScriptMode;
|
||||
|
||||
import org.apache.lucene.search.BoostQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
@ -237,8 +238,10 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
|
||||
Set<ScriptEngineService> engines = new HashSet<>();
|
||||
engines.add(mockScriptEngine);
|
||||
List<ScriptContext.Plugin> customContexts = new ArrayList<>();
|
||||
ScriptEngineRegistry scriptEngineRegistry = new ScriptEngineRegistry(Collections
|
||||
.singletonList(new ScriptEngineRegistry.ScriptEngineRegistration(MockScriptEngine.class, MockScriptEngine.TYPES)));
|
||||
ScriptEngineRegistry scriptEngineRegistry =
|
||||
new ScriptEngineRegistry(Collections
|
||||
.singletonList(new ScriptEngineRegistry.ScriptEngineRegistration(MockScriptEngine.class,
|
||||
MockScriptEngine.TYPES, ScriptMode.ON)));
|
||||
bind(ScriptEngineRegistry.class).toInstance(scriptEngineRegistry);
|
||||
ScriptContextRegistry scriptContextRegistry = new ScriptContextRegistry(customContexts);
|
||||
bind(ScriptContextRegistry.class).toInstance(scriptContextRegistry);
|
||||
|
@ -21,6 +21,7 @@ package org.elasticsearch.script;
|
||||
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.script.ScriptMode;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.util.Arrays;
|
||||
@ -44,7 +45,10 @@ public class ScriptContextTests extends ESTestCase {
|
||||
.put("script.engine." + MockScriptEngine.NAME + ".inline." + PLUGIN_NAME + "_custom_exp_disabled_op", "false")
|
||||
.build();
|
||||
Set<ScriptEngineService> engines = new HashSet<>(Collections.singletonList(new MockScriptEngine()));
|
||||
ScriptEngineRegistry scriptEngineRegistry = new ScriptEngineRegistry(Collections.singletonList(new ScriptEngineRegistry.ScriptEngineRegistration(MockScriptEngine.class, MockScriptEngine.TYPES)));
|
||||
ScriptEngineRegistry scriptEngineRegistry =
|
||||
new ScriptEngineRegistry(Collections.singletonList(new ScriptEngineRegistry.ScriptEngineRegistration(MockScriptEngine.class,
|
||||
MockScriptEngine.TYPES,
|
||||
ScriptMode.ON)));
|
||||
List<ScriptContext.Plugin> customContexts = Arrays.asList(
|
||||
new ScriptContext.Plugin(PLUGIN_NAME, "custom_op"),
|
||||
new ScriptContext.Plugin(PLUGIN_NAME, "custom_exp_disabled_op"),
|
||||
|
@ -99,6 +99,7 @@ public class ScriptModesTests extends ESTestCase {
|
||||
assertThat(scriptModes, notNullValue());
|
||||
//2 is the number of engines (native excluded), custom is counted twice though as it's associated with two different names
|
||||
int numberOfSettings = 2 * ScriptType.values().length * scriptContextRegistry.scriptContexts().size();
|
||||
numberOfSettings += 6; // for top-level inline/store/file settings
|
||||
assertThat(scriptModes.scriptModes.size(), equalTo(numberOfSettings));
|
||||
if (assertAllSettingsWereChecked) {
|
||||
assertThat(checkedSettings.size(), equalTo(numberOfSettings));
|
||||
@ -109,7 +110,7 @@ public class ScriptModesTests extends ESTestCase {
|
||||
public void testDefaultSettings() {
|
||||
this.scriptModes = new ScriptModes(scriptSettings, Settings.EMPTY);
|
||||
assertScriptModesAllOps(ScriptMode.ON, ALL_LANGS, ScriptType.FILE);
|
||||
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.STORED, ScriptType.INLINE);
|
||||
assertScriptModesAllOps(ScriptMode.OFF, ALL_LANGS, ScriptType.STORED, ScriptType.INLINE);
|
||||
}
|
||||
|
||||
public void testMissingSetting() {
|
||||
@ -148,10 +149,10 @@ public class ScriptModesTests extends ESTestCase {
|
||||
assertScriptModesAllOps(ScriptMode.ON, ALL_LANGS, ScriptType.FILE);
|
||||
}
|
||||
if (randomScriptTypesSet.contains(ScriptType.STORED) == false) {
|
||||
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.STORED);
|
||||
assertScriptModesAllOps(ScriptMode.OFF, ALL_LANGS, ScriptType.STORED);
|
||||
}
|
||||
if (randomScriptTypesSet.contains(ScriptType.INLINE) == false) {
|
||||
assertScriptModesAllOps(ScriptMode.SANDBOX, ALL_LANGS, ScriptType.INLINE);
|
||||
assertScriptModesAllOps(ScriptMode.OFF, ALL_LANGS, ScriptType.INLINE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,19 +180,19 @@ public class ScriptModesTests extends ESTestCase {
|
||||
|
||||
ScriptContext[] complementOf = complementOf(randomScriptContexts);
|
||||
assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.FILE}, complementOf);
|
||||
assertScriptModes(ScriptMode.SANDBOX, ALL_LANGS, new ScriptType[]{ScriptType.STORED, ScriptType.INLINE}, complementOf);
|
||||
assertScriptModes(ScriptMode.OFF, ALL_LANGS, new ScriptType[]{ScriptType.STORED, ScriptType.INLINE}, complementOf);
|
||||
}
|
||||
|
||||
public void testConflictingScriptTypeAndOpGenericSettings() {
|
||||
ScriptContext scriptContext = randomFrom(scriptContexts);
|
||||
Settings.Builder builder = Settings.builder().put("script" + "." + scriptContext.getKey(), randomFrom(DISABLE_VALUES))
|
||||
.put("script.stored", randomFrom(ENABLE_VALUES)).put("script.inline", "sandbox");
|
||||
.put("script.stored", randomFrom(ENABLE_VALUES)).put("script.inline", "true");
|
||||
//operations generic settings have precedence over script type generic settings
|
||||
this.scriptModes = new ScriptModes(scriptSettings, builder.build());
|
||||
assertScriptModesAllTypes(ScriptMode.OFF, ALL_LANGS, scriptContext);
|
||||
ScriptContext[] complementOf = complementOf(scriptContext);
|
||||
assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.FILE, ScriptType.STORED}, complementOf);
|
||||
assertScriptModes(ScriptMode.SANDBOX, ALL_LANGS, new ScriptType[]{ScriptType.INLINE}, complementOf);
|
||||
assertScriptModes(ScriptMode.ON, ALL_LANGS, new ScriptType[]{ScriptType.INLINE}, complementOf);
|
||||
}
|
||||
|
||||
private void assertScriptModesAllOps(ScriptMode expectedScriptMode, Set<String> langs, ScriptType... scriptTypes) {
|
||||
@ -208,8 +209,10 @@ public class ScriptModesTests extends ESTestCase {
|
||||
assert scriptContexts.length > 0;
|
||||
for (String lang : langs) {
|
||||
for (ScriptType scriptType : scriptTypes) {
|
||||
checkedSettings.add("script.engine." + lang + "." + scriptType);
|
||||
for (ScriptContext scriptContext : scriptContexts) {
|
||||
assertThat(lang + "." + scriptType + "." + scriptContext.getKey() + " doesn't have the expected value", scriptModes.getScriptMode(lang, scriptType, scriptContext), equalTo(expectedScriptMode));
|
||||
assertThat(lang + "." + scriptType + "." + scriptContext.getKey() + " doesn't have the expected value",
|
||||
scriptModes.getScriptMode(lang, scriptType, scriptContext), equalTo(expectedScriptMode));
|
||||
checkedSettings.add(lang + "." + scriptType + "." + scriptContext);
|
||||
}
|
||||
}
|
||||
@ -251,11 +254,6 @@ public class ScriptModesTests extends ESTestCase {
|
||||
return Collections.singletonList(TYPES.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSandboxed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String script, Map<String, String> params) {
|
||||
return null;
|
||||
|
@ -41,11 +41,14 @@ import org.junit.Before;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
@ -57,6 +60,8 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
|
||||
private ResourceWatcherService resourceWatcherService;
|
||||
private ScriptEngineService scriptEngineService;
|
||||
private ScriptEngineService dangerousScriptEngineService;
|
||||
private Set<ScriptEngineService> services;
|
||||
private Map<String, ScriptEngineService> scriptEnginesByLangMap;
|
||||
private ScriptEngineRegistry scriptEngineRegistry;
|
||||
private ScriptContextRegistry scriptContextRegistry;
|
||||
@ -70,8 +75,8 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
|
||||
static {
|
||||
DEFAULT_SCRIPT_MODES.put(ScriptType.FILE, ScriptMode.ON);
|
||||
DEFAULT_SCRIPT_MODES.put(ScriptType.STORED, ScriptMode.SANDBOX);
|
||||
DEFAULT_SCRIPT_MODES.put(ScriptType.INLINE, ScriptMode.SANDBOX);
|
||||
DEFAULT_SCRIPT_MODES.put(ScriptType.STORED, ScriptMode.OFF);
|
||||
DEFAULT_SCRIPT_MODES.put(ScriptType.INLINE, ScriptMode.OFF);
|
||||
}
|
||||
|
||||
@Before
|
||||
@ -83,6 +88,10 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
.build();
|
||||
resourceWatcherService = new ResourceWatcherService(baseSettings, null);
|
||||
scriptEngineService = new TestEngineService();
|
||||
dangerousScriptEngineService = new TestDangerousEngineService();
|
||||
services = new HashSet<>(2);
|
||||
services.add(scriptEngineService);
|
||||
services.add(dangerousScriptEngineService);
|
||||
scriptEnginesByLangMap = ScriptModesTests.buildScriptEnginesByLangMap(Collections.singleton(scriptEngineService));
|
||||
//randomly register custom script contexts
|
||||
int randomInt = randomIntBetween(0, 3);
|
||||
@ -100,7 +109,10 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
String context = plugin + "_" + operation;
|
||||
contexts.put(context, new ScriptContext.Plugin(plugin, operation));
|
||||
}
|
||||
scriptEngineRegistry = new ScriptEngineRegistry(Collections.singletonList(new ScriptEngineRegistry.ScriptEngineRegistration(TestEngineService.class, TestEngineService.TYPES)));
|
||||
List<ScriptEngineRegistry.ScriptEngineRegistration> registries = new ArrayList<>(2);
|
||||
registries.add(new ScriptEngineRegistry.ScriptEngineRegistration(TestEngineService.class, TestEngineService.TYPES, ScriptMode.ON));
|
||||
registries.add(new ScriptEngineRegistry.ScriptEngineRegistration(TestDangerousEngineService.class, TestDangerousEngineService.TYPES));
|
||||
scriptEngineRegistry = new ScriptEngineRegistry(registries);
|
||||
scriptContextRegistry = new ScriptContextRegistry(contexts.values());
|
||||
scriptSettings = new ScriptSettings(scriptEngineRegistry, scriptContextRegistry);
|
||||
scriptContexts = scriptContextRegistry.scriptContexts().toArray(new ScriptContext[scriptContextRegistry.scriptContexts().size()]);
|
||||
@ -112,7 +124,7 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
private void buildScriptService(Settings additionalSettings) throws IOException {
|
||||
Settings finalSettings = Settings.builder().put(baseSettings).put(additionalSettings).build();
|
||||
Environment environment = new Environment(finalSettings);
|
||||
scriptService = new ScriptService(finalSettings, environment, Collections.singleton(scriptEngineService), resourceWatcherService, scriptEngineRegistry, scriptContextRegistry, scriptSettings) {
|
||||
scriptService = new ScriptService(finalSettings, environment, services, resourceWatcherService, scriptEngineRegistry, scriptContextRegistry, scriptSettings) {
|
||||
@Override
|
||||
String getScriptFromClusterState(ClusterState state, String scriptLang, String id) {
|
||||
//mock the script that gets retrieved from an index
|
||||
@ -208,20 +220,14 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
if (rarely()) {
|
||||
builder.put("script.file", randomFrom(ScriptModesTests.ENABLE_VALUES));
|
||||
}
|
||||
if (rarely()) {
|
||||
builder.put("script.stored", "sandbox");
|
||||
}
|
||||
if (rarely()) {
|
||||
builder.put("script.inline", "sandbox");
|
||||
}
|
||||
buildScriptService(builder.build());
|
||||
createFileScripts("groovy", "mustache", "test");
|
||||
createFileScripts("groovy", "mustache", "dtest");
|
||||
|
||||
for (ScriptContext scriptContext : scriptContexts) {
|
||||
//custom engine is sandboxed, all scripts are enabled by default
|
||||
assertCompileAccepted("test", "script", ScriptType.INLINE, scriptContext);
|
||||
assertCompileAccepted("test", "script", ScriptType.STORED, scriptContext);
|
||||
assertCompileAccepted("test", "file_script", ScriptType.FILE, scriptContext);
|
||||
// only file scripts are accepted by default
|
||||
assertCompileRejected("dtest", "script", ScriptType.INLINE, scriptContext);
|
||||
assertCompileRejected("dtest", "script", ScriptType.STORED, scriptContext);
|
||||
assertCompileAccepted("dtest", "file_script", ScriptType.FILE, scriptContext);
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,9 +272,6 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
case OFF:
|
||||
builder.put("script" + "." + entry.getKey().getScriptType(), "false");
|
||||
break;
|
||||
case SANDBOX:
|
||||
builder.put("script" + "." + entry.getKey().getScriptType(), "sandbox");
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (Map.Entry<ScriptContext, ScriptMode> entry : scriptContextSettings.entrySet()) {
|
||||
@ -276,13 +279,9 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
case ON:
|
||||
builder.put("script" + "." + entry.getKey().getKey(), "true");
|
||||
break;
|
||||
|
||||
case OFF:
|
||||
builder.put("script" + "." + entry.getKey().getKey(), "false");
|
||||
break;
|
||||
case SANDBOX:
|
||||
builder.put("script" + "." + entry.getKey().getKey(), "sandbox");
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (Map.Entry<String, ScriptMode> entry : engineSettings.entrySet()) {
|
||||
@ -298,14 +297,11 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
case OFF:
|
||||
builder.put("script.engine" + "." + lang + "." + part2, "false");
|
||||
break;
|
||||
case SANDBOX:
|
||||
builder.put("script.engine" + "." + lang + "." + part2, "sandbox");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
buildScriptService(builder.build());
|
||||
createFileScripts("groovy", "expression", "mustache", "test");
|
||||
createFileScripts("groovy", "expression", "mustache", "dtest");
|
||||
|
||||
for (ScriptType scriptType : ScriptType.values()) {
|
||||
//make sure file scripts have a different name than inline ones.
|
||||
@ -313,7 +309,7 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
String script = scriptType == ScriptType.FILE ? "file_script" : "script";
|
||||
for (ScriptContext scriptContext : this.scriptContexts) {
|
||||
//fallback mechanism: 1) engine specific settings 2) op based settings 3) source based settings
|
||||
ScriptMode scriptMode = engineSettings.get(scriptEngineService.getTypes().get(0) + "." + scriptType + "." + scriptContext.getKey());
|
||||
ScriptMode scriptMode = engineSettings.get(dangerousScriptEngineService.getTypes().get(0) + "." + scriptType + "." + scriptContext.getKey());
|
||||
if (scriptMode == null) {
|
||||
scriptMode = scriptContextSettings.get(scriptContext);
|
||||
}
|
||||
@ -324,7 +320,7 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
scriptMode = DEFAULT_SCRIPT_MODES.get(scriptType);
|
||||
}
|
||||
|
||||
for (String lang : scriptEngineService.getTypes()) {
|
||||
for (String lang : dangerousScriptEngineService.getTypes()) {
|
||||
switch (scriptMode) {
|
||||
case ON:
|
||||
assertCompileAccepted(lang, script, scriptType, scriptContext);
|
||||
@ -332,13 +328,6 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
case OFF:
|
||||
assertCompileRejected(lang, script, scriptType, scriptContext);
|
||||
break;
|
||||
case SANDBOX:
|
||||
if (scriptEngineService.isSandboxed()) {
|
||||
assertCompileAccepted(lang, script, scriptType, scriptContext);
|
||||
} else {
|
||||
assertCompileRejected(lang, script, scriptType, scriptContext);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -401,6 +390,7 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
public void testCompilationStatsOnCacheHit() throws IOException {
|
||||
Settings.Builder builder = Settings.builder();
|
||||
builder.put(ScriptService.SCRIPT_CACHE_SIZE_SETTING.getKey(), 1);
|
||||
builder.put("script.inline", "true");
|
||||
buildScriptService(builder.build());
|
||||
ClusterState state = ClusterState.builder(new ClusterName("_name")).build();
|
||||
scriptService.executable(new Script("1+1", ScriptType.INLINE, "test", null), randomFrom(scriptContexts), Collections.emptyMap(), state);
|
||||
@ -426,6 +416,7 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
public void testCacheEvictionCountedInCacheEvictionsStats() throws IOException {
|
||||
Settings.Builder builder = Settings.builder();
|
||||
builder.put(ScriptService.SCRIPT_CACHE_SIZE_SETTING.getKey(), 1);
|
||||
builder.put("script.inline", "true");
|
||||
buildScriptService(builder.build());
|
||||
ClusterState state = ClusterState.builder(new ClusterName("_name")).build();
|
||||
scriptService.executable(new Script("1+1", ScriptType.INLINE, "test", null), randomFrom(scriptContexts), Collections.emptyMap(), state);
|
||||
@ -437,6 +428,7 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
public void testDefaultLanguage() throws IOException {
|
||||
Settings.Builder builder = Settings.builder();
|
||||
builder.put("script.default_lang", "test");
|
||||
builder.put("script.inline", "true");
|
||||
buildScriptService(builder.build());
|
||||
CompiledScript script = scriptService.compile(new Script("1 + 1", ScriptType.INLINE, null, null),
|
||||
randomFrom(scriptContexts), Collections.emptyMap(), emptyClusterState());
|
||||
@ -552,8 +544,45 @@ public class ScriptServiceTests extends ESTestCase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSandboxed() {
|
||||
return true;
|
||||
public Object compile(String script, Map<String, String> params) {
|
||||
return "compiled_" + script;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutableScript executable(final CompiledScript compiledScript, @Nullable Map<String, Object> vars) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchScript search(CompiledScript compiledScript, SearchLookup lookup, @Nullable Map<String, Object> vars) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scriptRemoved(CompiledScript script) {
|
||||
// Nothing to do here
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestDangerousEngineService implements ScriptEngineService {
|
||||
|
||||
public static final List<String> TYPES = Collections.unmodifiableList(Arrays.asList("dtest"));
|
||||
|
||||
public static final List<String> EXTENSIONS = Collections.unmodifiableList(Arrays.asList("dtest"));
|
||||
|
||||
@Override
|
||||
public List<String> getTypes() {
|
||||
return TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getExtensions() {
|
||||
return EXTENSIONS;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -110,11 +110,6 @@ public class ScriptSettingsTests extends ESTestCase {
|
||||
return Collections.singletonList(TYPES.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSandboxed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String script, Map<String, String> params) {
|
||||
return null;
|
||||
|
@ -55,6 +55,7 @@ import org.elasticsearch.script.ScriptContext;
|
||||
import org.elasticsearch.script.ScriptContextRegistry;
|
||||
import org.elasticsearch.script.ScriptEngineRegistry;
|
||||
import org.elasticsearch.script.ScriptEngineService;
|
||||
import org.elasticsearch.script.ScriptMode;
|
||||
import org.elasticsearch.script.ScriptModule;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.script.ScriptSettings;
|
||||
@ -144,8 +145,10 @@ public abstract class BasePipelineAggregationTestCase<AF extends PipelineAggrega
|
||||
Set<ScriptEngineService> engines = new HashSet<>();
|
||||
engines.add(mockScriptEngine);
|
||||
List<ScriptContext.Plugin> customContexts = new ArrayList<>();
|
||||
ScriptEngineRegistry scriptEngineRegistry = new ScriptEngineRegistry(Collections
|
||||
.singletonList(new ScriptEngineRegistry.ScriptEngineRegistration(MockScriptEngine.class, MockScriptEngine.TYPES)));
|
||||
ScriptEngineRegistry scriptEngineRegistry =
|
||||
new ScriptEngineRegistry(Collections
|
||||
.singletonList(new ScriptEngineRegistry.ScriptEngineRegistration(MockScriptEngine.class,
|
||||
MockScriptEngine.TYPES, ScriptMode.ON)));
|
||||
bind(ScriptEngineRegistry.class).toInstance(scriptEngineRegistry);
|
||||
ScriptContextRegistry scriptContextRegistry = new ScriptContextRegistry(customContexts);
|
||||
bind(ScriptContextRegistry.class).toInstance(scriptContextRegistry);
|
||||
|
@ -28,6 +28,7 @@ import org.elasticsearch.script.LeafSearchScript;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptEngineRegistry;
|
||||
import org.elasticsearch.script.ScriptEngineService;
|
||||
import org.elasticsearch.script.ScriptMode;
|
||||
import org.elasticsearch.script.ScriptModule;
|
||||
import org.elasticsearch.script.ScriptService.ScriptType;
|
||||
import org.elasticsearch.script.SearchScript;
|
||||
@ -369,7 +370,7 @@ public class AvgIT extends AbstractNumericTestCase {
|
||||
}
|
||||
|
||||
public void onModule(ScriptModule module) {
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(ExtractFieldScriptEngine.class, ExtractFieldScriptEngine.TYPES));
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(ExtractFieldScriptEngine.class, ExtractFieldScriptEngine.TYPES, ScriptMode.ON));
|
||||
}
|
||||
|
||||
}
|
||||
@ -397,11 +398,6 @@ public class AvgIT extends AbstractNumericTestCase {
|
||||
return TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSandboxed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String script, Map<String, String> params) {
|
||||
return script;
|
||||
@ -501,7 +497,7 @@ public class AvgIT extends AbstractNumericTestCase {
|
||||
}
|
||||
|
||||
public void onModule(ScriptModule module) {
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(FieldValueScriptEngine.class, FieldValueScriptEngine.TYPES));
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(FieldValueScriptEngine.class, FieldValueScriptEngine.TYPES, ScriptMode.ON));
|
||||
}
|
||||
|
||||
}
|
||||
@ -529,11 +525,6 @@ public class AvgIT extends AbstractNumericTestCase {
|
||||
return TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSandboxed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String script, Map<String, String> params) {
|
||||
return script;
|
||||
|
@ -28,6 +28,7 @@ import org.elasticsearch.script.LeafSearchScript;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptEngineRegistry;
|
||||
import org.elasticsearch.script.ScriptEngineService;
|
||||
import org.elasticsearch.script.ScriptMode;
|
||||
import org.elasticsearch.script.ScriptModule;
|
||||
import org.elasticsearch.script.ScriptService.ScriptType;
|
||||
import org.elasticsearch.script.SearchScript;
|
||||
@ -364,7 +365,7 @@ public class SumIT extends AbstractNumericTestCase {
|
||||
}
|
||||
|
||||
public void onModule(ScriptModule module) {
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(ExtractFieldScriptEngine.class, ExtractFieldScriptEngine.TYPES));
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(ExtractFieldScriptEngine.class, ExtractFieldScriptEngine.TYPES, ScriptMode.ON));
|
||||
}
|
||||
|
||||
}
|
||||
@ -393,11 +394,6 @@ public class SumIT extends AbstractNumericTestCase {
|
||||
return TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSandboxed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String script, Map<String, String> params) {
|
||||
return script;
|
||||
@ -498,7 +494,7 @@ public class SumIT extends AbstractNumericTestCase {
|
||||
}
|
||||
|
||||
public void onModule(ScriptModule module) {
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(FieldValueScriptEngine.class, FieldValueScriptEngine.TYPES));
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(FieldValueScriptEngine.class, FieldValueScriptEngine.TYPES, ScriptMode.ON));
|
||||
}
|
||||
|
||||
}
|
||||
@ -527,11 +523,6 @@ public class SumIT extends AbstractNumericTestCase {
|
||||
return TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSandboxed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String script, Map<String, String> params) {
|
||||
return script;
|
||||
|
@ -28,6 +28,7 @@ import org.elasticsearch.script.LeafSearchScript;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptEngineRegistry;
|
||||
import org.elasticsearch.script.ScriptEngineService;
|
||||
import org.elasticsearch.script.ScriptMode;
|
||||
import org.elasticsearch.script.ScriptModule;
|
||||
import org.elasticsearch.script.ScriptService.ScriptType;
|
||||
import org.elasticsearch.script.SearchScript;
|
||||
@ -223,7 +224,7 @@ public class ValueCountIT extends ESIntegTestCase {
|
||||
}
|
||||
|
||||
public void onModule(ScriptModule module) {
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(FieldValueScriptEngine.class, FieldValueScriptEngine.TYPES));
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(FieldValueScriptEngine.class, FieldValueScriptEngine.TYPES, ScriptMode.ON));
|
||||
}
|
||||
|
||||
}
|
||||
@ -251,11 +252,6 @@ public class ValueCountIT extends ESIntegTestCase {
|
||||
return TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSandboxed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String script, Map<String, String> params) {
|
||||
return script;
|
||||
|
@ -43,6 +43,7 @@ import org.elasticsearch.script.ExecutableScript;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptEngineRegistry;
|
||||
import org.elasticsearch.script.ScriptEngineService;
|
||||
import org.elasticsearch.script.ScriptMode;
|
||||
import org.elasticsearch.script.ScriptModule;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.script.SearchScript;
|
||||
@ -93,7 +94,7 @@ public class UpdateIT extends ESIntegTestCase {
|
||||
}
|
||||
|
||||
public void onModule(ScriptModule module) {
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(PutFieldValuesScriptEngine.class, PutFieldValuesScriptEngine.TYPES));
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(PutFieldValuesScriptEngine.class, PutFieldValuesScriptEngine.TYPES, ScriptMode.ON));
|
||||
}
|
||||
|
||||
}
|
||||
@ -118,11 +119,6 @@ public class UpdateIT extends ESIntegTestCase {
|
||||
return TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSandboxed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String script, Map<String, String> params) {
|
||||
return new Object(); // unused
|
||||
@ -187,7 +183,7 @@ public class UpdateIT extends ESIntegTestCase {
|
||||
}
|
||||
|
||||
public void onModule(ScriptModule module) {
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(FieldIncrementScriptEngine.class, FieldIncrementScriptEngine.TYPES));
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(FieldIncrementScriptEngine.class, FieldIncrementScriptEngine.TYPES, ScriptMode.ON));
|
||||
}
|
||||
|
||||
}
|
||||
@ -212,11 +208,6 @@ public class UpdateIT extends ESIntegTestCase {
|
||||
return TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSandboxed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String script, Map<String, String> params) {
|
||||
return script;
|
||||
@ -274,7 +265,7 @@ public class UpdateIT extends ESIntegTestCase {
|
||||
}
|
||||
|
||||
public void onModule(ScriptModule module) {
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(ScriptedUpsertScriptEngine.class, ScriptedUpsertScriptEngine.TYPES));
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(ScriptedUpsertScriptEngine.class, ScriptedUpsertScriptEngine.TYPES, ScriptMode.ON));
|
||||
}
|
||||
|
||||
}
|
||||
@ -299,11 +290,6 @@ public class UpdateIT extends ESIntegTestCase {
|
||||
return TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSandboxed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String script, Map<String, String> params) {
|
||||
return new Object(); // unused
|
||||
@ -361,7 +347,7 @@ public class UpdateIT extends ESIntegTestCase {
|
||||
}
|
||||
|
||||
public void onModule(ScriptModule module) {
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(ExtractContextInSourceScriptEngine.class, ExtractContextInSourceScriptEngine.TYPES));
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(ExtractContextInSourceScriptEngine.class, ExtractContextInSourceScriptEngine.TYPES, ScriptMode.ON));
|
||||
}
|
||||
|
||||
}
|
||||
@ -386,11 +372,6 @@ public class UpdateIT extends ESIntegTestCase {
|
||||
return TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSandboxed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String script, Map<String, String> params) {
|
||||
return new Object(); // unused
|
||||
|
@ -51,16 +51,6 @@ All settings with a `netty` infix have been replaced by their already existing
|
||||
supported and should be replaced by the superseding setting
|
||||
`transport.bind_host`.
|
||||
|
||||
==== Script mode settings
|
||||
|
||||
Previously script mode settings (e.g., "script.inline: true",
|
||||
"script.engine.groovy.inline.aggs: false", etc.) accepted the values
|
||||
`on`, `true`, `1`, and `yes` for enabling a scripting mode, and the
|
||||
values `off`, `false`, `0`, and `no` for disabling a scripting mode.
|
||||
The variants `on`, `1`, and `yes` for enabling and `off`, `0`,
|
||||
and `no` for disabling are no longer supported.
|
||||
|
||||
|
||||
==== Security manager settings
|
||||
|
||||
The option to disable the security manager `security.manager.enabled` has been
|
||||
@ -241,6 +231,8 @@ a fallback realtime setting for the get and mget APIs when realtime
|
||||
wasn't specified. Now if the parameter isn't specified we always
|
||||
default to true.
|
||||
|
||||
=== Script settings
|
||||
|
||||
==== Indexed script settings
|
||||
|
||||
Due to the fact that indexed script has been replaced by stored
|
||||
@ -248,7 +240,21 @@ scripts the following settings have been replaced to:
|
||||
|
||||
* `script.indexed` has been replaced by `script.stored`
|
||||
* `script.engine.*.indexed.aggs` has been replaced by `script.engine.*.stored.aggs` (where `*` represents the script language, like `groovy`, `mustache`, `plainless` etc.)
|
||||
* `script.engine.*.stored.mapping` has been replaced by `script.engine.*.stored.mapping` (where `*` represents the script language, like `groovy`, `mustache`, `plainless` etc.)
|
||||
* `script.engine.*.stored.search` has been replaced by `script.engine.*.stored.search` (where `*` represents the script language, like `groovy`, `mustache`, `plainless` etc.)
|
||||
* `script.engine.*.stored.update` has been replaced by `script.engine.*.stored.update` (where `*` represents the script language, like `groovy`, `mustache`, `plainless` etc.)
|
||||
* `script.engine.*.stored.plugin` has been replaced by `script.engine.*.stored.plugin` (where `*` represents the script language, like `groovy`, `mustache`, `plainless` etc.)
|
||||
* `script.engine.*.indexed.mapping` has been replaced by `script.engine.*.stored.mapping` (where `*` represents the script language, like `groovy`, `mustache`, `plainless` etc.)
|
||||
* `script.engine.*.indexed.search` has been replaced by `script.engine.*.stored.search` (where `*` represents the script language, like `groovy`, `mustache`, `plainless` etc.)
|
||||
* `script.engine.*.indexed.update` has been replaced by `script.engine.*.stored.update` (where `*` represents the script language, like `groovy`, `mustache`, `plainless` etc.)
|
||||
* `script.engine.*.indexed.plugin` has been replaced by `script.engine.*.stored.plugin` (where `*` represents the script language, like `groovy`, `mustache`, `plainless` etc.)
|
||||
|
||||
==== Script mode settings
|
||||
|
||||
Previously script mode settings (e.g., "script.inline: true",
|
||||
"script.engine.groovy.inline.aggs: false", etc.) accepted a wide range of
|
||||
"truthy" or "falsy" values. This is now much stricter and supports only the
|
||||
`true` and `false` options.
|
||||
|
||||
|
||||
==== Script sandbox settings removed
|
||||
|
||||
Prior to 5.0 a third option could be specified for the `script.inline` and
|
||||
`script.stored` settings ("sandbox"). This has been removed, You can now only
|
||||
set `script.line: true` or `script.stored: true`.
|
||||
|
@ -24,23 +24,18 @@ and give the most flexibility.
|
||||
[cols="<,<,<",options="header",]
|
||||
|=======================================================================
|
||||
|Language
|
||||
|Sandboxed
|
||||
|Required plugin
|
||||
|
||||
|<<modules-scripting-painless, `painless`>>
|
||||
|yes
|
||||
|built-in
|
||||
|
||||
|<<modules-scripting-groovy, `groovy`>>
|
||||
|<<modules-scripting-security, no>>
|
||||
|built-in
|
||||
|
||||
|{plugins}/lang-javascript.html[`javascript`]
|
||||
|<<modules-scripting-security, no>>
|
||||
|{plugins}/lang-javascript.html[`lang-javascript`]
|
||||
|
||||
|{plugins}/lang-python.html[`python`]
|
||||
|<<modules-scripting-security, no>>
|
||||
|{plugins}/lang-python.html[`lang-python`]
|
||||
|
||||
|=======================================================================
|
||||
@ -54,35 +49,23 @@ certain tasks.
|
||||
[cols="<,<,<,<",options="header",]
|
||||
|=======================================================================
|
||||
|Language
|
||||
|Sandboxed
|
||||
|Required plugin
|
||||
|Purpose
|
||||
|
||||
|<<modules-scripting-expression, `expression`>>
|
||||
|yes
|
||||
|built-in
|
||||
|fast custom ranking and sorting
|
||||
|
||||
|<<search-template, `mustache`>>
|
||||
|yes
|
||||
|built-in
|
||||
|templates
|
||||
|
||||
|<<modules-scripting-native, `java`>>
|
||||
|n/a
|
||||
|you write it!
|
||||
|expert API
|
||||
|
||||
|=======================================================================
|
||||
|
||||
[WARNING]
|
||||
.Scripts and security
|
||||
=================================================
|
||||
|
||||
Languages that are sandboxed are designed with security in mind. However, non-
|
||||
sandboxed languages can be a security issue, please read
|
||||
<<modules-scripting-security, Scripting and security>> for more details.
|
||||
|
||||
=================================================
|
||||
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
[[modules-scripting-groovy]]
|
||||
=== Groovy Scripting Language
|
||||
|
||||
Groovy is the default scripting language available in Elasticsearch. Although
|
||||
limited by the <<java-security-manager,Java Security Manager>>, it is not a
|
||||
sandboxed language and only `file` scripts may be used by default.
|
||||
Groovy is the default scripting language available in Elasticsearch. Although
|
||||
limited by the <<java-security-manager,Java Security Manager>>, only `file`
|
||||
scripts may be used by default.
|
||||
|
||||
Enabling `inline` or `stored` Groovy scripting is a security risk and should
|
||||
only be considered if your Elasticsearch cluster is protected from the outside
|
||||
|
@ -53,22 +53,20 @@ Each of these settings takes one of these values:
|
||||
[horizontal]
|
||||
`false`:: Scripting is enabled.
|
||||
`true`:: Scripting is disabled.
|
||||
`sandbox`:: Scripting is enabled only for sandboxed languages.
|
||||
|
||||
The default values are the following:
|
||||
|
||||
[source,yaml]
|
||||
-----------------------------------
|
||||
script.inline: sandbox
|
||||
script.stored: sandbox
|
||||
script.inline: false
|
||||
script.stored: false
|
||||
script.file: true
|
||||
-----------------------------------
|
||||
|
||||
NOTE: Global scripting settings affect the `mustache` scripting language.
|
||||
<<search-template,Search templates>> internally use the `mustache` language,
|
||||
and will still be enabled by default as the `mustache` engine is sandboxed,
|
||||
but they will be enabled/disabled according to fine-grained settings
|
||||
specified in `elasticsearch.yml`.
|
||||
<<search-template,Search templates>> internally use the `mustache` language, and
|
||||
will be disabled by default, but they can be enabled/disabled according to
|
||||
fine-grained settings specified in `elasticsearch.yml`.
|
||||
|
||||
[[security-script-context]]
|
||||
[float]
|
||||
@ -88,9 +86,9 @@ of using the generic `plugin` category. Those operations can be referred to
|
||||
in the following form: `${pluginName}_${operation}`.
|
||||
|
||||
The following example disables scripting for `update` and `plugin` operations,
|
||||
regardless of the script source or language. Scripts can still be executed
|
||||
from sandboxed languages as part of `aggregations`, `search` and plugins
|
||||
execution though, as the above defaults still get applied.
|
||||
regardless of the script source or language. Scripts can be executed from
|
||||
languages as part of `aggregations`, `search` and plugins execution though,
|
||||
assuming they are enabled in the scripting settings.
|
||||
|
||||
[source,yaml]
|
||||
-----------------------------------
|
||||
@ -114,6 +112,13 @@ Fine-grained settings have the form:
|
||||
script.engine.{lang}.{source}.{context}: true|false
|
||||
------------------------
|
||||
|
||||
And
|
||||
|
||||
[source,yaml]
|
||||
------------------------
|
||||
script.engine.{lang}.{inline|file|stored}: true|false
|
||||
------------------------
|
||||
|
||||
For example:
|
||||
|
||||
[source,yaml]
|
||||
@ -122,14 +127,16 @@ script.inline: false <1>
|
||||
script.stored: false <1>
|
||||
script.file: false <1>
|
||||
|
||||
script.engine.groovy.stored.search: true <2>
|
||||
script.engine.groovy.stored.aggs: true <2>
|
||||
script.engine.groovy.inline: true <2>
|
||||
script.engine.groovy.stored.search: true <3>
|
||||
script.engine.groovy.stored.aggs: true <3>
|
||||
|
||||
script.engine.mustache.stored.search: true <3>
|
||||
script.engine.mustache.stored.search: true <4>
|
||||
-----------------------------------
|
||||
<1> Disable all scripting from any source.
|
||||
<2> Allow stored Groovy scripts to be used for search and aggregations.
|
||||
<3> Allow stored Mustache templates to be used for search.
|
||||
<2> Allow inline Groovy scripts for all operations
|
||||
<3> Allow stored Groovy scripts to be used for search and aggregations.
|
||||
<4> Allow stored Mustache templates to be used for search.
|
||||
|
||||
[[java-security-manager]]
|
||||
[float]
|
||||
|
@ -110,12 +110,15 @@ second version is only compiled once.
|
||||
[[modules-scripting-file-scripts]]
|
||||
=== File-based Scripts
|
||||
|
||||
To increase security, non-sandboxed languages can only be specified in script
|
||||
files stored on every node in the cluster. File scripts must be saved in the
|
||||
`scripts` directory whose default location depends on whether you use the
|
||||
<<zip-targz-layout,`zip`/`tar.gz`>> (`$ES_HOME/config/scripts/`),
|
||||
<<rpm-layout,RPM>>, or <<deb-layout,Debian>> package. The default may be
|
||||
changed with the `path.script` setting.
|
||||
To increase security, scripts for languages that are not deemed to be safe by
|
||||
default can only be specified in files stored on every node in the cluster. File
|
||||
scripts must be saved in the `scripts` directory whose default location depends
|
||||
on whether you use the <<zip-targz-layout,`zip`/`tar.gz`>>
|
||||
(`$ES_HOME/config/scripts/`), <<rpm-layout,RPM>>, or <<deb-layout,Debian>>
|
||||
package. The default may be changed with the `path.script` setting.
|
||||
|
||||
The languages which are assumed to be safe by default are: painless,
|
||||
expressions, and mustache (used for query templates).
|
||||
|
||||
Any files placed in the `scripts` directory will be compiled automatically
|
||||
when the node starts up and then <<reload-scripts,every 60 seconds thereafter>>.
|
||||
|
@ -25,10 +25,10 @@ For more information on how Mustache templating and what kind of templating you
|
||||
can do with it check out the http://mustache.github.io/mustache.5.html[online
|
||||
documentation of the mustache project].
|
||||
|
||||
NOTE: The mustache language is implemented in elasticsearch as a sandboxed
|
||||
scripting language, hence it obeys settings that may be used to enable or
|
||||
disable scripts per language, source and operation as described in
|
||||
<<enable-dynamic-scripting, scripting docs>>
|
||||
NOTE: The mustache language is implemented in elasticsearch as a scripting
|
||||
language, hence it obeys settings that may be used to enable or disable scripts
|
||||
per language, source and operation as described in <<enable-dynamic-scripting,
|
||||
scripting docs>>
|
||||
|
||||
[float]
|
||||
==== More template examples
|
||||
|
@ -21,6 +21,7 @@ package org.elasticsearch.script.expression;
|
||||
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.script.ScriptEngineRegistry;
|
||||
import org.elasticsearch.script.ScriptMode;
|
||||
import org.elasticsearch.script.ScriptModule;
|
||||
|
||||
public class ExpressionPlugin extends Plugin {
|
||||
@ -36,6 +37,7 @@ public class ExpressionPlugin extends Plugin {
|
||||
}
|
||||
|
||||
public void onModule(ScriptModule module) {
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(ExpressionScriptEngineService.class, ExpressionScriptEngineService.TYPES));
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(ExpressionScriptEngineService.class,
|
||||
ExpressionScriptEngineService.TYPES, ScriptMode.ON));
|
||||
}
|
||||
}
|
||||
|
@ -79,11 +79,6 @@ public class ExpressionScriptEngineService extends AbstractComponent implements
|
||||
return TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSandboxed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String script, Map<String, String> params) {
|
||||
// classloader created here
|
||||
|
@ -170,11 +170,6 @@ public class GroovyScriptEngineService extends AbstractComponent implements Scri
|
||||
return TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSandboxed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String script, Map<String, String> params) {
|
||||
try {
|
||||
|
@ -21,6 +21,7 @@ package org.elasticsearch.script.mustache;
|
||||
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.script.ScriptEngineRegistry;
|
||||
import org.elasticsearch.script.ScriptMode;
|
||||
import org.elasticsearch.script.ScriptModule;
|
||||
|
||||
public class MustachePlugin extends Plugin {
|
||||
@ -36,6 +37,7 @@ public class MustachePlugin extends Plugin {
|
||||
}
|
||||
|
||||
public void onModule(ScriptModule module) {
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(MustacheScriptEngineService.class, MustacheScriptEngineService.TYPES));
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(MustacheScriptEngineService.class,
|
||||
MustacheScriptEngineService.TYPES, ScriptMode.ON));
|
||||
}
|
||||
}
|
||||
|
@ -121,11 +121,6 @@ public final class MustacheScriptEngineService extends AbstractComponent impleme
|
||||
return TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSandboxed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutableScript executable(CompiledScript compiledScript,
|
||||
@Nullable Map<String, Object> vars) {
|
||||
|
@ -94,6 +94,7 @@ public class TemplateQueryParserTests extends ESTestCase {
|
||||
.put(Environment.PATH_CONF_SETTING.getKey(), this.getDataPath("config"))
|
||||
.put("node.name", getClass().getName())
|
||||
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)
|
||||
.put("script.inline", "true")
|
||||
.build();
|
||||
final Client proxy = (Client) Proxy.newProxyInstance(
|
||||
Client.class.getClassLoader(),
|
||||
|
@ -21,6 +21,7 @@ package org.elasticsearch.painless;
|
||||
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.script.ScriptEngineRegistry;
|
||||
import org.elasticsearch.script.ScriptMode;
|
||||
import org.elasticsearch.script.ScriptModule;
|
||||
|
||||
/**
|
||||
@ -40,6 +41,6 @@ public final class PainlessPlugin extends Plugin {
|
||||
|
||||
public void onModule(final ScriptModule module) {
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(
|
||||
PainlessScriptEngineService.class, PainlessScriptEngineService.TYPES));
|
||||
PainlessScriptEngineService.class, PainlessScriptEngineService.TYPES, ScriptMode.ON));
|
||||
}
|
||||
}
|
||||
|
@ -116,15 +116,6 @@ public final class PainlessScriptEngineService extends AbstractComponent impleme
|
||||
return EXTENSIONS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the engine is secure.
|
||||
* @return Always true as the engine should be secure at runtime.
|
||||
*/
|
||||
@Override
|
||||
public boolean isSandboxed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles a Painless script with the specified parameters.
|
||||
* @param script The code to be compiled.
|
||||
|
@ -168,11 +168,6 @@ public class JavaScriptScriptEngineService extends AbstractComponent implements
|
||||
return Collections.unmodifiableList(Arrays.asList("js"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSandboxed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String script, Map<String, String> params) {
|
||||
Context ctx = Context.enter();
|
||||
|
@ -105,11 +105,6 @@ public class PythonScriptEngineService extends AbstractComponent implements Scri
|
||||
return Collections.unmodifiableList(Arrays.asList("py"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSandboxed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String script, Map<String, String> params) {
|
||||
// classloader created here
|
||||
|
@ -23,6 +23,7 @@ import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.script.ScriptMode;
|
||||
import org.elasticsearch.search.lookup.SearchLookup;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -55,7 +56,8 @@ public class MockScriptEngine implements ScriptEngineService {
|
||||
}
|
||||
|
||||
public void onModule(ScriptModule module) {
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(MockScriptEngine.class, MockScriptEngine.TYPES));
|
||||
module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(MockScriptEngine.class,
|
||||
MockScriptEngine.TYPES, ScriptMode.ON));
|
||||
}
|
||||
|
||||
}
|
||||
@ -70,11 +72,6 @@ public class MockScriptEngine implements ScriptEngineService {
|
||||
return TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSandboxed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compile(String script, Map<String, String> params) {
|
||||
return script;
|
||||
|
@ -1622,9 +1622,7 @@ public abstract class ESIntegTestCase extends ESTestCase {
|
||||
// from failing on nodes without enough disk space
|
||||
.put(DiskThresholdDecider.CLUSTER_ROUTING_ALLOCATION_LOW_DISK_WATERMARK_SETTING.getKey(), "1b")
|
||||
.put(DiskThresholdDecider.CLUSTER_ROUTING_ALLOCATION_HIGH_DISK_WATERMARK_SETTING.getKey(), "1b")
|
||||
.put("script.stored", "true")
|
||||
.put("script.inline", "true")
|
||||
// wait short time for other active shards before actually deleting, default 30s not needed in tests
|
||||
// wait short time for other active shards before actually deleting, default 30s not needed in tests
|
||||
.put(IndicesStore.INDICES_STORE_DELETE_SHARD_TIMEOUT.getKey(), new TimeValue(1, TimeUnit.SECONDS));
|
||||
return builder.build();
|
||||
}
|
||||
|
@ -178,9 +178,6 @@ public abstract class ESSingleNodeTestCase extends ESTestCase {
|
||||
// This needs to tie into the ESIntegTestCase#indexSettings() method
|
||||
.put(Environment.PATH_SHARED_DATA_SETTING.getKey(), createTempDir().getParent())
|
||||
.put("node.name", nodeName())
|
||||
|
||||
.put("script.inline", "true")
|
||||
.put("script.stored", "true")
|
||||
.put(EsExecutors.PROCESSORS_SETTING.getKey(), 1) // limit the number of threads created
|
||||
.put("http.enabled", false)
|
||||
.put(Node.NODE_LOCAL_SETTING.getKey(), true)
|
||||
|
Loading…
x
Reference in New Issue
Block a user