Skip to content

Commit 66fec71

Browse files
committed
Rewrite the scripting security docs (#23930)
They needed to be updated now that Painless is the default and the non-sandboxed scripting languages are going away or gone.
1 parent 672afed commit 66fec71

4 files changed

Lines changed: 111 additions & 73 deletions

File tree

docs/build.gradle

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ buildRestTests.expectedUnconvertedCandidates = [
9191
'reference/migration/migrate_5_0/mapping.asciidoc',
9292
'reference/migration/migrate_5_0/scripting.asciidoc',
9393
'reference/release-notes/5.0.0-alpha5.asciidoc',
94-
'reference/modules/scripting/security.asciidoc',
9594
'reference/modules/cross-cluster-search.asciidoc', // this is hart to test since we need 2 clusters -- maybe we can trick it into referencing itself...
9695
'reference/query-dsl/exists-query.asciidoc',
9796
'reference/search/field-stats.asciidoc',

docs/plugins/authors.asciidoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ Read more in {ref}/integration-tests.html#changing-node-configuration[Changing N
7676

7777

7878
[float]
79+
[[plugin-authors-jsm]]
7980
=== Java Security permissions
8081

8182
Some plugins may need additional security permissions. A plugin can include
@@ -111,4 +112,3 @@ AccessController.doPrivileged(
111112

112113
See http://www.oracle.com/technetwork/java/seccodeguide-139067.html[Secure Coding Guidelines for Java SE]
113114
for more information.
114-

docs/reference/modules/scripting/security.asciidoc

Lines changed: 108 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,115 @@
11
[[modules-scripting-security]]
22
=== Scripting and security
33

4-
You should never run Elasticsearch as the `root` user, as this would allow a
5-
script to access or do *anything* on your server, without limitations.
4+
While Elasticsearch contributors make every effort to prevent scripts from
5+
running amok, security is something best done in
6+
https://en.wikipedia.org/wiki/Defense_in_depth_(computing)[layers] because
7+
all software has bugs and it is important to minimize the risk of failure in
8+
any security layer. Find below rules of thumb for how to keep Elasticsearch
9+
from being a vulnerability.
610

7-
You should not expose Elasticsearch directly to users, but instead have a
8-
proxy application inbetween. If you *do* intend to expose Elasticsearch
9-
directly to your users, then you have to decide whether you trust them enough
10-
to run scripts on your box or not, and apply the appropriate safety measures.
11-
12-
[[enable-dynamic-scripting]]
1311
[float]
14-
=== Enabling dynamic scripting
15-
16-
The `script.*` settings allow for <<security-script-fine,fine-grained>>
17-
control of which script languages (e.g `groovy`, `painless`) are allowed to
18-
run in which context ( e.g. `search`, `aggs`, `update`), and where the script
19-
source is allowed to come from (i.e. `inline`, `stored`, `file`).
12+
=== Do not run as root
13+
First and foremost, never run Elasticsearch as the `root` user as this would
14+
allow any successful effort to circumvent the other security layers to do
15+
*anything* on your server. Elasticsearch will refuse to start if it detects
16+
that it is running as `root` but this is so important that it is worth double
17+
and triple checking.
2018

21-
For instance, the following setting enables `stored` `update` scripts for
22-
`groovy`:
19+
[float]
20+
=== Do not expose Elasticsearch directly to users
21+
Do not expose Elasticsearch directly to users, instead have an application
22+
make requests on behalf of users. If this is not possible, have an application
23+
to sanitize requests from users. If *that* is not possible then have some
24+
mechanism to track which users did what. Understand that it is quite possible
25+
to write a <<search, `_search`>> that overwhelms Elasticsearch and brings down
26+
the cluster. All such searches should be considered bugs and the Elasticsearch
27+
contributors make an effort to prevent this but they are still possible.
2328

24-
[source,yaml]
25-
----------------
26-
script.engine.groovy.inline.update: true
27-
----------------
29+
[float]
30+
=== Do not expose Elasticsearch directly to the Internet
31+
Do not expose Elasticsearch to the Internet, instead have an application
32+
make requests on behalf of the Internet. Do not entertain the thought of having
33+
an application "sanitize" requests to Elasticsearch. Understand that it is
34+
possible for a sufficiently determined malicious user to write searches that
35+
overwhelm the Elasticsearch cluster and bring it down. For example:
36+
37+
Good:
38+
* Users type text into a search box and the text is sent directly to a
39+
<<query-dsl-match-query>>, <<query-dsl-match-query-phrase>>,
40+
<<query-dsl-simple-query-string-query>>, or any of the <<search-suggesters>>.
41+
* Running a script with any of the above queries that was written as part of
42+
the application development process.
43+
* Running a script with `params` provided by users.
44+
* User actions makes documents with a fixed structure.
45+
46+
Bad:
47+
* Users can write arbitrary scripts, queries, `_search` requests.
48+
* User actions make documents with structure defined by users.
2849

29-
Less fine-grained settings exist which allow you to enable or disable scripts
30-
for all sources, all languages, or all contexts. The following settings
31-
enable `inline` and `stored` scripts for all languages in all contexts:
50+
[float]
51+
[[modules-scripting-security-do-no-weaken]]
52+
=== Do not weaken script security settings
53+
By default Elasticsearch will run inline, stored, and filesystem scripts for
54+
sandboxed languages, namely the scripting language Painless, the template
55+
language Mustache, and the expression language Expressions. These *ought* to be
56+
safe to expose to trusted users and to your application servers because they
57+
have strong security sandboxes. By default Elasticsearch will only run
58+
filesystem scripts for non-sandboxed languages and enabling them is a poor
59+
choice because:
60+
1. This drops a layer of security, leaving only Elasticsearch's builtin
61+
<<modules-scripting-other-layers, security layers>>.
62+
2. Non-sandboxed scripts have unchecked access to Elasticsearch's internals and
63+
can cause all kinds of trouble if misused.
3264

33-
[source,yaml]
34-
-----------------------------------
35-
script.inline: true
36-
script.stored: true
37-
-----------------------------------
3865

39-
WARNING: The above settings mean that anybody who can send requests to your
40-
Elasticsearch instance can run whatever scripts they choose! This is a
41-
security risk and may well lead to your Elasticsearch cluster being
42-
compromised.
66+
[float]
67+
[[modules-scripting-other-layers]]
68+
=== Other security layers
69+
In addition to user privileges and script sandboxing Elasticsearch uses the
70+
http://www.oracle.com/technetwork/java/seccodeguide-139067.html[Java Security Manager]
71+
and native security tools as additional layers of security.
72+
73+
As part of its startup sequence Elasticsearch enables the Java Security Manager
74+
which limits the actions that can be taken by portions of the code. Painless
75+
uses this to limit the actions that generated Painless scripts can take,
76+
preventing them from being able to do things like write files and listen to
77+
sockets.
78+
79+
Elasticsearch uses
80+
https://en.wikipedia.org/wiki/Seccomp[seccomp] in Linux,
81+
https://www.chromium.org/developers/design-documents/sandbox/osx-sandboxing-design[Seatbelt]
82+
in macOS, and
83+
https://msdn.microsoft.com/en-us/library/windows/desktop/ms684147[ActiveProcessLimit]
84+
on Windows to prevent Elasticsearch from forking or executing other processes.
85+
86+
Below this we describe the security settings for scripts and how you can
87+
change from the defaults described above. You should be very, very careful
88+
when allowing more than the defaults. Any extra permissions weakens the total
89+
security of the Elasticsearch deployment.
4390

4491
[[security-script-source]]
4592
[float]
4693
=== Script source settings
4794

48-
Scripts may be enabled or disabled depending on their source: `inline`,
49-
`stored` in the cluster state, or from a `file` on each node in the cluster.
50-
Each of these settings takes one of these values:
51-
52-
53-
[horizontal]
54-
`false`:: Scripting is disabled.
55-
`true`:: Scripting is enabled.
56-
57-
The default values are the following:
95+
Which scripts Elasticsearch will execute where is controlled by settings
96+
starting with `scripts.`. The simplest settings allow scripts to be enabled
97+
or disabled based on where they are stored. For example:
5898

5999
[source,yaml]
60100
-----------------------------------
61-
script.inline: false
62-
script.stored: false
63-
script.file: true
101+
script.inline: false <1>
102+
script.stored: false <2>
103+
script.file: true <3>
64104
-----------------------------------
105+
<1> Refuse to run scripts provided inline in the API.
106+
<2> Refuse to run scripts stored using the API.
107+
<3> Run scripts found on the filesystem in `/etc/elasticsearch/scripts`
108+
(rpm or deb) or `config/scripts` (zip or tar).
65109

66-
NOTE: Global scripting settings affect the `mustache` scripting language.
67-
<<search-template,Search templates>> internally use the `mustache` language,
68-
and will still be enabled by default as the `mustache` engine is sandboxed,
69-
but they will be enabled/disabled according to fine-grained settings
70-
specified in `elasticsearch.yml`.
110+
NOTE: These settings override the defaults mentioned
111+
<<modules-scripting-security-do-no-weaken, above>>. Recreating the defaults
112+
requires more fine grained settings described <<security-script-fine, below>>.
71113

72114
[[security-script-context]]
73115
[float]
@@ -102,15 +144,13 @@ script.plugin: false
102144
=== Fine-grained script settings
103145

104146
First, the high-level script settings described above are applied in order
105-
(context settings have precedence over source settings). Then, fine-grained
147+
(context settings have precedence over source settings). Then fine-grained
106148
settings which include the script language take precedence over any high-level
107-
settings.
108-
109-
Fine-grained settings have the form:
149+
settings. They have two forms:
110150

111151
[source,yaml]
112152
------------------------
113-
script.engine.{lang}.{source}.{context}: true|false
153+
script.engine.{lang}.{inline|file|stored}.{context}: true|false
114154
------------------------
115155

116156
And
@@ -128,36 +168,36 @@ script.inline: false <1>
128168
script.stored: false <1>
129169
script.file: false <1>
130170
131-
script.engine.groovy.inline: true <2>
132-
script.engine.groovy.stored.search: true <3>
133-
script.engine.groovy.stored.aggs: true <3>
171+
script.engine.painless.inline: true <2>
172+
script.engine.painless.stored.search: true <3>
173+
script.engine.painless.stored.aggs: true <3>
134174
135-
script.engine.mustache.stored.search: true <4>
175+
script.engine.mustache.stored.search: true <4>
136176
-----------------------------------
137177
<1> Disable all scripting from any source.
138-
<2> Allow inline Groovy scripts for all operations
139-
<3> Allow stored Groovy scripts to be used for search and aggregations.
178+
<2> Allow inline Painless scripts for all operations.
179+
<3> Allow stored Painless scripts to be used for search and aggregations.
140180
<4> Allow stored Mustache templates to be used for search.
141181

142182
[[java-security-manager]]
143183
[float]
144184
=== Java Security Manager
145185

146-
Elasticsearch runs with the https://docs.oracle.com/javase/tutorial/essential/environment/security.html[Java Security Manager]
147-
enabled by default. The security policy in Elasticsearch locks down the
186+
As mentioned above, Elasticsearch runs with the https://docs.oracle.com/javase/tutorial/essential/environment/security.html[Java Security Manager]
187+
enabled by default. The security policy in Elasticsearch locks down the
148188
permissions granted to each class to the bare minimum required to operate.
149189
The benefit of doing this is that it severely limits the attack vectors
150190
available to a hacker.
151191

152-
Restricting permissions is particularly important with scripting languages
153-
like Groovy and Javascript which are designed to do anything that can be done
154-
in Java itself, including writing to the file system, opening sockets to
155-
remote servers, etc.
192+
Restricting permissions is particularly important for non-sandboxed scripting
193+
languages like Groovy and Javascript which are designed to do anything that can
194+
be done in Java itself, including writing to the file system, opening sockets
195+
to remote servers, etc.
156196

157197
[float]
158198
=== Script Classloader Whitelist
159199

160-
Scripting languages are only allowed to load classes which appear in a
200+
Groovy makes an effort to prevent loading classes which do not appear in a
161201
hardcoded whitelist that can be found in
162202
https://github.com/elastic/elasticsearch/blob/{branch}/core/src/main/java/org/elasticsearch/script/ClassPermission.java[`org.elasticsearch.script.ClassPermission`].
163203

@@ -287,4 +327,3 @@ doing so.
287327
======================================
288328

289329
See http://docs.oracle.com/javase/7/docs/technotes/guides/security/PolicyFiles.html for more information.
290-

docs/reference/search/search-template.asciidoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ documentation of the mustache project].
2828

2929
NOTE: The mustache language is implemented in elasticsearch as a sandboxed
3030
scripting language, hence it obeys settings that may be used to enable or
31-
disable scripts per language, source and operation as described in
32-
<<enable-dynamic-scripting, scripting docs>>
31+
disable scripts per language, source and operation as described in the
32+
<<security-script-source, scripting docs>>
3333

3434
[float]
3535
==== More template examples

0 commit comments

Comments
 (0)