Elasticsearch exposed to the internet
For most of the last decade, Elasticsearch was the single most common source of mass data breaches. Not because it was uniquely insecure, but because of a combination that turned out to be catastrophic at scale: it shipped with no authentication, it was easy to bind to a routable address, and it held precisely the data that makes headlines — aggregated logs, user records, entire application datasets.
The numbers were staggering. Individual exposed clusters leaked hundreds of
millions of records at a time; in aggregate, billions. None of it required an
exploit. Scanners found port 9200, made a GET request, and got everything.
Version 8.0 (2022) closed the default — security is now on out of the box. But
three populations remain exposed: 7.x clusters (security off by default), modern
clusters where someone turned security off to
fix a connection error, and clusters bound to
0.0.0.0 behind a misconfigured firewall.
What an open cluster gives away
Section titled “What an open cluster gives away”With security off, a single unauthenticated request does it:
curl http://your.es:9200/_cat/indices?v # every index, and its sizecurl http://your.es:9200/_search?size=10000 # the documentscurl -X DELETE http://your.es:9200/_all # all of it, goneNo credential, no exploit, no privilege escalation. Read everything, or delete
everything, in one line. The _cat/indices endpoint is a table of contents for
the breach.
And like the MongoDB wave, open Elasticsearch attracted ransom crews: databases wiped and replaced with a single index demanding payment. As with MongoDB, paying is pointless — much of the time the data was never copied, only deleted, and there is nothing to return.
It used to be worse than a data breach
Section titled “It used to be worse than a data breach”Worth knowing, because it explains why some old advice is so insistent about scripting.
Before the modern sandboxed scripting engine, Elasticsearch executed dynamic scripts in languages (MVEL, then Groovy) that could reach out of the sandbox. CVE-2014-3120 and CVE-2015-1427 turned an open cluster into remote code execution — a search query that ran shell commands on the host. Those were headline RCEs in their day.
Modern Elasticsearch uses Painless, a purpose-built sandboxed language, and the dangerous dynamic-scripting engines are gone. So a current open cluster is usually a total data compromise rather than host code execution — which is the same shape as MongoDB: the data is the loss, not the machine. That’s still catastrophic; it’s just not a shell.
Do not let that reassure you into leaving scripting-era versions running. A 7.x or older cluster that’s both open and outdated may still be exposed to the historic RCE paths, on top of everything else unpatched.
The shortest path from exposed to closed
Section titled “The shortest path from exposed to closed”- Enable security — the wall that should have been there. On 8.x/9.x it’s a setting that was flipped off; put it back.
- Bind to a private interface — off
0.0.0.0, onto the one interface your clients use. - Firewall 9200 and 9300 — an unreachable cluster needs no login, and 9300 should never be reachable from outside your node network.
- Give apps scoped credentials — so a leak later isn’t the whole cluster.
Steps 1 and 2 are settings plus a restart. Do them before you finish reading.
Related
Section titled “Related”- Hardening Elasticsearch — the full checklist.
- Enable security — the control that makes this impossible.