Skip to content

MongoDB exposed to the internet

Severity: criticalApplies to: Any reachable instance

An unauthenticated MongoDB reachable from an untrusted network is not a brute-force target. There is nothing to brute force. Authentication is off by default, so an attacker connects and is, immediately, an administrator: every collection readable, every database droppable.

This is the only service on this site where the exposed state requires no attack at all. It is why MongoDB is the database that got ransomed at scale.

What actually happened, and why it matters now

Section titled “What actually happened, and why it matters now”

Starting in late 2016 and running through 2017, tens of thousands of internet-facing MongoDB instances were found by automated scanning, had their databases copied or simply dropped, and were left with a single collection containing a ransom demand. No exploit was involved. The tooling connected, ran dropDatabase, and inserted a note.

The preconditions were MongoDB’s defaults at the time: no authentication, and a bindIp default of every interface. MongoDB 3.6 changed the binding default to loopback, which is why the wave subsided — but the authentication default never changed. It is still off.

So the modern version of this is one step away: any change that widens the bind — a container’s published port, bindIpAll added to fix a connection error, a security group with an over-broad rule — restores the 2017 conditions exactly, because the second layer was never there.

Worth being precise, because the reaction should differ too.

An open Redis or MySQL is a path to running code on the host — Redis via CONFIG SET dir and a file write, MySQL via FILE and UDFs. MongoDB has no equivalent. Its server-side JavaScript runs in a sandboxed interpreter with no filesystem or shell access, and there is no mechanism to make mongod write an arbitrary file to an arbitrary path.

So an open MongoDB is usually not a host compromise. It is a total data compromise: every document read, and every document destroyable, in one connection. For most people that is the worse of the two.

Don’t let that be reassuring. “They only got all the data” is not a good outcome, and the ransom crews did not need a shell to end companies.

  1. Enable authorization — the layer that should have been there. Read the page first; the order of operations is the whole trick.
  2. Bind to a private interface — and check the container’s published port, not just the config.
  3. Firewall 27017.
  4. Fix the roles — so a leaked credential isn’t root.

Steps 2 and 3 take minutes and stop the bleeding. Step 1 is the one that means it can’t happen again.