|
@@ -1,73 +1,115 @@
|
|
|
[[modules-scripting-security]]
|
|
|
=== Scripting and security
|
|
|
|
|
|
-You should never run Elasticsearch as the `root` user, as this would allow a
|
|
|
-script to access or do *anything* on your server, without limitations.
|
|
|
+While Elasticsearch contributors make every effort to prevent scripts from
|
|
|
+running amok, security is something best done in
|
|
|
+https://en.wikipedia.org/wiki/Defense_in_depth_(computing)[layers] because
|
|
|
+all software has bugs and it is important to minimize the risk of failure in
|
|
|
+any security layer. Find below rules of thumb for how to keep Elasticsearch
|
|
|
+from being a vulnerability.
|
|
|
|
|
|
-You should not expose Elasticsearch directly to users, but instead have a
|
|
|
-proxy application inbetween. If you *do* intend to expose Elasticsearch
|
|
|
-directly to your users, then you have to decide whether you trust them enough
|
|
|
-to run scripts on your box or not, and apply the appropriate safety measures.
|
|
|
-
|
|
|
-[[enable-dynamic-scripting]]
|
|
|
[float]
|
|
|
-=== Enabling dynamic scripting
|
|
|
+=== Do not run as root
|
|
|
+First and foremost, never run Elasticsearch as the `root` user as this would
|
|
|
+allow any successful effort to circumvent the other security layers to do
|
|
|
+*anything* on your server. Elasticsearch will refuse to start if it detects
|
|
|
+that it is running as `root` but this is so important that it is worth double
|
|
|
+and triple checking.
|
|
|
|
|
|
-The `script.*` settings allow for <<security-script-fine,fine-grained>>
|
|
|
-control of which script languages (e.g `painless`) are allowed to
|
|
|
-run in which context ( e.g. `search`, `aggs`, `update`), and where the script
|
|
|
-source is allowed to come from (i.e. `inline`, `stored`, `file`).
|
|
|
+[float]
|
|
|
+=== Do not expose Elasticsearch directly to users
|
|
|
+Do not expose Elasticsearch directly to users, instead have an application
|
|
|
+make requests on behalf of users. If this is not possible, have an application
|
|
|
+to sanitize requests from users. If *that* is not possible then have some
|
|
|
+mechanism to track which users did what. Understand that it is quite possible
|
|
|
+to write a <<search, `_search`>> that overwhelms Elasticsearch and brings down
|
|
|
+the cluster. All such searches should be considered bugs and the Elasticsearch
|
|
|
+contributors make an effort to prevent this but they are still possible.
|
|
|
|
|
|
-For instance, the following setting enables `stored` `update` scripts for
|
|
|
-`painless`:
|
|
|
+[float]
|
|
|
+=== Do not expose Elasticsearch directly to the Internet
|
|
|
+Do not expose Elasticsearch to the Internet, instead have an application
|
|
|
+make requests on behalf of the Internet. Do not entertain the thought of having
|
|
|
+an application "sanitize" requests to Elasticsearch. Understand that it is
|
|
|
+possible for a sufficiently determined malicious user to write searches that
|
|
|
+overwhelm the Elasticsearch cluster and bring it down. For example:
|
|
|
+
|
|
|
+Good:
|
|
|
+* Users type text into a search box and the text is sent directly to a
|
|
|
+<<query-dsl-match-query>>, <<query-dsl-match-query-phrase>>,
|
|
|
+<<query-dsl-simple-query-string-query>>, or any of the <<search-suggesters>>.
|
|
|
+* Running a script with any of the above queries that was written as part of
|
|
|
+the application development process.
|
|
|
+* Running a script with `params` provided by users.
|
|
|
+* User actions makes documents with a fixed structure.
|
|
|
+
|
|
|
+Bad:
|
|
|
+* Users can write arbitrary scripts, queries, `_search` requests.
|
|
|
+* User actions make documents with structure defined by users.
|
|
|
|
|
|
-[source,yaml]
|
|
|
-----------------
|
|
|
-script.engine.painless.inline.update: true
|
|
|
-----------------
|
|
|
+[float]
|
|
|
+[[modules-scripting-security-do-no-weaken]]
|
|
|
+=== Do not weaken script security settings
|
|
|
+By default Elasticsearch will run inline, stored, and filesystem scripts for
|
|
|
+sandboxed languages, namely the scripting language Painless, the template
|
|
|
+language Mustache, and the expression language Expressions. These *ought* to be
|
|
|
+safe to expose to trusted users and to your application servers because they
|
|
|
+have strong security sandboxes. By default Elasticsearch will only run
|
|
|
+filesystem scripts for non-sandboxed languages and enabling them is a poor
|
|
|
+choice because:
|
|
|
+1. This drops a layer of security, leaving only Elasticsearch's builtin
|
|
|
+<<modules-scripting-other-layers, security layers>>.
|
|
|
+2. Non-sandboxed scripts have unchecked access to Elasticsearch's internals and
|
|
|
+can cause all kinds of trouble if misused.
|
|
|
|
|
|
-Less fine-grained settings exist which allow you to enable or disable scripts
|
|
|
-for all sources, all languages, or all contexts. The following settings
|
|
|
-enable `inline` and `stored` scripts for all languages in all contexts:
|
|
|
|
|
|
-[source,yaml]
|
|
|
------------------------------------
|
|
|
-script.inline: true
|
|
|
-script.stored: true
|
|
|
------------------------------------
|
|
|
-
|
|
|
-WARNING: The above settings mean that anybody who can send requests to your
|
|
|
-Elasticsearch instance can run whatever scripts they choose! This is a
|
|
|
-security risk and may well lead to your Elasticsearch cluster being
|
|
|
-compromised.
|
|
|
+[float]
|
|
|
+[[modules-scripting-other-layers]]
|
|
|
+=== Other security layers
|
|
|
+In addition to user privileges and script sandboxing Elasticsearch uses the
|
|
|
+http://www.oracle.com/technetwork/java/seccodeguide-139067.html[Java Security Manager]
|
|
|
+and native security tools as additional layers of security.
|
|
|
+
|
|
|
+As part of its startup sequence Elasticsearch enables the Java Security Manager
|
|
|
+which limits the actions that can be taken by portions of the code. Painless
|
|
|
+uses this to limit the actions that generated Painless scripts can take,
|
|
|
+preventing them from being able to do things like write files and listen to
|
|
|
+sockets.
|
|
|
+
|
|
|
+Elasticsearch uses
|
|
|
+https://en.wikipedia.org/wiki/Seccomp[seccomp] in Linux,
|
|
|
+https://www.chromium.org/developers/design-documents/sandbox/osx-sandboxing-design[Seatbelt]
|
|
|
+in macOS, and
|
|
|
+https://msdn.microsoft.com/en-us/library/windows/desktop/ms684147[ActiveProcessLimit]
|
|
|
+on Windows to prevent Elasticsearch from forking or executing other processes.
|
|
|
+
|
|
|
+Below this we describe the security settings for scripts and how you can
|
|
|
+change from the defaults described above. You should be very, very careful
|
|
|
+when allowing more than the defaults. Any extra permissions weakens the total
|
|
|
+security of the Elasticsearch deployment.
|
|
|
|
|
|
[[security-script-source]]
|
|
|
[float]
|
|
|
=== Script source settings
|
|
|
|
|
|
-Scripts may be enabled or disabled depending on their source: `inline`,
|
|
|
-`stored` in the cluster state, or from a `file` on each node in the cluster.
|
|
|
-Each of these settings takes one of these values:
|
|
|
-
|
|
|
-
|
|
|
-[horizontal]
|
|
|
-`false`:: Scripting is disabled.
|
|
|
-`true`:: Scripting is enabled.
|
|
|
-
|
|
|
-The default values are the following:
|
|
|
+Which scripts Elasticsearch will execute where is controlled by settings
|
|
|
+starting with `scripts.`. The simplest settings allow scripts to be enabled
|
|
|
+or disabled based on where they are stored. For example:
|
|
|
|
|
|
[source,yaml]
|
|
|
-----------------------------------
|
|
|
-script.inline: false
|
|
|
-script.stored: false
|
|
|
-script.file: true
|
|
|
+script.inline: false <1>
|
|
|
+script.stored: false <2>
|
|
|
+script.file: true <3>
|
|
|
-----------------------------------
|
|
|
+<1> Refuse to run scripts provided inline in the API.
|
|
|
+<2> Refuse to run scripts stored using the API.
|
|
|
+<3> Run scripts found on the filesystem in `/etc/elasticsearch/scripts`
|
|
|
+(rpm or deb) or `config/scripts` (zip or tar).
|
|
|
|
|
|
-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`.
|
|
|
+NOTE: These settings override the defaults mentioned
|
|
|
+<<modules-scripting-security-do-no-weaken, above>>. Recreating the defaults
|
|
|
+requires more fine grained settings described <<security-script-fine, below>>.
|
|
|
|
|
|
[[security-script-context]]
|
|
|
[float]
|
|
@@ -102,15 +144,13 @@ script.plugin: false
|
|
|
=== Fine-grained script settings
|
|
|
|
|
|
First, the high-level script settings described above are applied in order
|
|
|
-(context settings have precedence over source settings). Then, fine-grained
|
|
|
+(context settings have precedence over source settings). Then fine-grained
|
|
|
settings which include the script language take precedence over any high-level
|
|
|
-settings.
|
|
|
-
|
|
|
-Fine-grained settings have the form:
|
|
|
+settings. They have two forms:
|
|
|
|
|
|
[source,yaml]
|
|
|
------------------------
|
|
|
-script.engine.{lang}.{source}.{context}: true|false
|
|
|
+script.engine.{lang}.{inline|file|stored}.{context}: true|false
|
|
|
------------------------
|
|
|
|
|
|
And
|
|
@@ -132,124 +172,9 @@ script.engine.painless.inline: true <2>
|
|
|
script.engine.painless.stored.search: true <3>
|
|
|
script.engine.painless.stored.aggs: true <3>
|
|
|
|
|
|
-script.engine.mustache.stored.search: true <4>
|
|
|
+script.engine.mustache.stored.search: true <4>
|
|
|
-----------------------------------
|
|
|
<1> Disable all scripting from any source.
|
|
|
-<2> Allow inline Groovy scripts for all operations
|
|
|
-<3> Allow stored Groovy scripts to be used for search and aggregations.
|
|
|
+<2> Allow inline Painless scripts for all operations.
|
|
|
+<3> Allow stored Painless scripts to be used for search and aggregations.
|
|
|
<4> Allow stored Mustache templates to be used for search.
|
|
|
-
|
|
|
-[[java-security-manager]]
|
|
|
-[float]
|
|
|
-=== Java Security Manager
|
|
|
-
|
|
|
-Elasticsearch runs with the https://docs.oracle.com/javase/tutorial/essential/environment/security.html[Java Security Manager]
|
|
|
-enabled by default. The security policy in Elasticsearch locks down the
|
|
|
-permissions granted to each class to the bare minimum required to operate.
|
|
|
-The benefit of doing this is that it severely limits the attack vectors
|
|
|
-available to a hacker.
|
|
|
-
|
|
|
-Restricting permissions is particularly important with scripting languages
|
|
|
-like Groovy which is designed to do anything that can be done
|
|
|
-in Java itself, including writing to the file system, opening sockets to
|
|
|
-remote servers, etc.
|
|
|
-
|
|
|
-[float]
|
|
|
-=== Script Classloader Whitelist
|
|
|
-
|
|
|
-Scripting languages are only allowed to load classes which appear in a
|
|
|
-hardcoded whitelist that can be found in
|
|
|
-https://github.com/elastic/elasticsearch/blob/{branch}/core/src/main/java/org/elasticsearch/script/ClassPermission.java[`org.elasticsearch.script.ClassPermission`].
|
|
|
-
|
|
|
-
|
|
|
-In a script, attempting to load a class that does not appear in the whitelist
|
|
|
-_may_ result in a `ClassNotFoundException`, for instance this script:
|
|
|
-
|
|
|
-[source,js]
|
|
|
-------------------------------
|
|
|
-GET _search
|
|
|
-{
|
|
|
- "script_fields": {
|
|
|
- "the_hour": {
|
|
|
- "script": "use(java.math.BigInteger); new BigInteger(1)"
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-------------------------------
|
|
|
-
|
|
|
-will return the following exception:
|
|
|
-
|
|
|
-[source,js]
|
|
|
-------------------------------
|
|
|
-{
|
|
|
- "reason": {
|
|
|
- "type": "script_exception",
|
|
|
- "reason": "failed to run inline script [use(java.math.BigInteger); new BigInteger(1)] using lang [painless]",
|
|
|
- "caused_by": {
|
|
|
- "type": "no_class_def_found_error",
|
|
|
- "reason": "java/math/BigInteger",
|
|
|
- "caused_by": {
|
|
|
- "type": "class_not_found_exception",
|
|
|
- "reason": "java.math.BigInteger"
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-------------------------------
|
|
|
-
|
|
|
-[float]
|
|
|
-== Dealing with Java Security Manager issues
|
|
|
-
|
|
|
-If you encounter issues with the Java Security Manager, you have two options
|
|
|
-for resolving these issues:
|
|
|
-
|
|
|
-[float]
|
|
|
-=== Fix the security problem
|
|
|
-
|
|
|
-The safest and most secure long term solution is to change the code causing
|
|
|
-the security issue. We recognise that this may take time to do correctly and
|
|
|
-so we provide the following two alternatives.
|
|
|
-
|
|
|
-[float]
|
|
|
-=== Customising the classloader whitelist
|
|
|
-
|
|
|
-The classloader whitelist can be customised by tweaking the local Java
|
|
|
-Security Policy either:
|
|
|
-
|
|
|
-* system wide: `$JAVA_HOME/lib/security/java.policy`,
|
|
|
-* for just the `elasticsearch` user: `/home/elasticsearch/.java.policy`
|
|
|
-* by adding a system property to the <<jvm-options,jvm.options>> configuration: `-Djava.security.policy=someURL`, or
|
|
|
-* via the `ES_JAVA_OPTS` environment variable with `-Djava.security.policy=someURL`:
|
|
|
-+
|
|
|
-[source,js]
|
|
|
----------------------------------
|
|
|
-export ES_JAVA_OPTS="${ES_JAVA_OPTS} -Djava.security.policy=file:///path/to/my.policy`
|
|
|
-./bin/elasticsearch
|
|
|
----------------------------------
|
|
|
-
|
|
|
-Permissions may be granted at the class, package, or global level. For instance:
|
|
|
-
|
|
|
-[source,js]
|
|
|
-----------------------------------
|
|
|
-grant {
|
|
|
- permission org.elasticsearch.script.ClassPermission "java.util.Base64"; // allow class
|
|
|
- permission org.elasticsearch.script.ClassPermission "java.util.*"; // allow package
|
|
|
- permission org.elasticsearch.script.ClassPermission "*"; // allow all (disables filtering basically)
|
|
|
-};
|
|
|
-----------------------------------
|
|
|
-
|
|
|
-[TIP]
|
|
|
-======================================
|
|
|
-
|
|
|
-Before adding classes to the whitelist, consider the security impact that it
|
|
|
-will have on Elasticsearch. Do you really need an extra class or can your code
|
|
|
-be rewritten in a more secure way?
|
|
|
-
|
|
|
-It is quite possible that we have not whitelisted a generically useful and
|
|
|
-safe class. If you have a class that you think should be whitelisted by
|
|
|
-default, please open an issue on GitHub and we will consider the impact of
|
|
|
-doing so.
|
|
|
-
|
|
|
-======================================
|
|
|
-
|
|
|
-See http://docs.oracle.com/javase/7/docs/technotes/guides/security/PolicyFiles.html for more information.
|