Overview
Elasticsearch scripts can place a heavy load on your cluster, particularly if the scripts are not written carefully with thought for the resources they may require. For this reason it is a best practice to limit both the type of scripts that can run on a cluster, and also the contexts in which scripts can run.
How to resolve it
Script settings are advanced settings which require you to have knowledge of how scripts on your cluster are implemented (if at all). If you are unsure of how scripting is implemented in your application, it is best not to change these values and leave the defaults. It is highly recommended to test this setting on a development or staging cluster to ensure it does not prevent your queries from working as expected.
script.allowed_types
You can set script.allowed_types to inline, stored, both or none. All of these values are perfectly valid, since many applications require scripts to enable them to run correctly. To set this value, you need to know whether your application requires the use of scripts or not, and how those scripts are implemented.
The below setting should be added to all of your nodes in elasticsearch.yml (it cannot be updated dynamically):
script.allowed_types: both
If you know your application does not require scripts to run, then set to none. If your application requires scripts, then it is good practice to store those scripts rather than use “inline” scripts. If you have carried out this optimisation in your application, then you can use “stored”.
Some applications (such as kibana) use inline scripts, so in this case, it may be necessary to use the “both” or “inline” settings.
Optimize your app by using stored scripts
There are both performance and security benefits to storing scripts on the cluster rather than using inline scripts.
To store a script in line, you can use the procedure as shown below:
Store the script with the name “add_count” on the cluster:
POST _scripts/add_count { "script": { "lang": "painless", "source": "ctx._source.count=ctx._source.count + params.my_increment" } }
Invoke the add_count script for an update by query command, passing in a parameter value to be used in the script:
POST my-index-000001/_update_by_query { "script": { "id": "add_count", "params":{ "my_increment":3 } }, "query": { "term": { "category": "my_category" } } }
script.allowed_contexts
To restrict the contexts allowed you need to know exactly which contexts your application requires to work. If you do not know which contexts you require, it is best to leave this setting as the default, which allows all contexts.
Possible contexts are:
ingest processor, update, update by query ,reindex, sort, similarity, weight, score, field, filter, minimum should match, metric aggregation initialization, metric aggregation map, metric aggregation combine, metric aggregation reduce, bucket script aggregation, bucket selector aggregation, watcher condition, watcher transform.
It is possible that plugins add further contexts that are not listed here.
If you want to restrict the contexts allowed to only certain contexts, then you can do so by adding the setting to all of your nodes in elasticsearch.yml like the example below (it cannot be updated dynamically):
script.allowed_contexts: score, update