Stanislav Kozlovski@kozlovski
An incredibly awful security vulnerability just got revealed in MongoDB.
So much that it got named after HeartBleed.
MongoBleed is a vulnerability affecting all MongoDB versions from 2017 to... today.
The exploit is simple. It's a buffer over read bug due to compression. Here's how it works 👇
Clients can send compressed requests to MongoDB.
The client helpfully includes the uncompressed size of the message so the server knows exactly how much memory to allocate when decompressing.
The server allocates a memory buffer with the given space. Due to how memory management and garbage collection in programs work, this allocated memory may already contain sensitive information that was copied earlier and is considered garbage now (eg because it's unreferenced).
This is technically fine - every computer program works that way because it is assumed that whatever unclaimed memory exists there will be overwritten. Unfortunately that’s exactly where the bug lies. 🙃
The server stupidly trusts the client’s provided uncompressed size. When a malicious client lies about the uncompressed size - e.g the actual decompressed size is 100 bytes, but the client says its 1MB - Mongo will treat the full 1MB block as the message.
It will unload the 100 byte decompressed msg into the buffer, yet treat the full 1MB block as the msg.
This is extremely problematic if you can get the server to return back parts of the 1MB block, because it could contain data you may not have access to.
That is exactly what the exploit does - it sends a badly-formatted BSON message. The server fails to parse it, and "helpfully" returns an error message containing the invalid message. The invalid message can be that whole 1MB block of foreign data.
To understand the exploit a bit better, you need to understand the MongoDB protocol.
• Mongo also uses its own TCP wire format (i.e doesn't use HTTP, gRPC or the like).
• BSON is Mongo's message format passed within the TCP wire format. BSON is basically JSON in binary form
• Commands in Mongo don't have particular endpoints or RPC names - rather, they are simply JSON-like messages. The action is inferred from the first key of the JSON.
For example, an insert request looks like this:
`{ "insert": "users", "documents": [ { "name": "alice", "age": 30 } ] }`
Every request to the server is therefore decoded into the BSON format as it’s parsed.
Critically, BSON parsing of field names (which are strings) work by parsing the field until you hit a null terminator byte (0x00).
It works exactly like strings in C, which have their own rich history of vulnerabilities.
We can now tie things together:
1. The client lies to the the server that its request has a big uncompressed size, so the server allocates a large block of memory
2. The client sends an invalid BSON with a field which does NOT contain the null terminator (0x00)
3. The server naively tries to parse the BSON field in that allocated block until it hits the first null byte. The first null byte is encountered in some foreign data since the BSON literally doesn't have it
4. The server realizes this is a completely invalid BSON message so it responds with an error.
5. The error response contains the invalid BSON "field". Critically, the server parsed garbage data from the heap in step 3), so it returns that data in the response.
Congrats. If the garbage contains passwords or other sensitive info, you’ve hacked MongoDB!
Hackers exploit this by sending many malicious requests per second and then attempting to reconstruct the pieces of garbage they received back.
What’s critical about this vulnerability is that it works on ANY internet-accessible unpatched instance of MongoDB. 💀
You don’t need to authenticate with the server, because this whole request/response parsing cycle happens before the server can even authenticate.
Obviously you can’t authenticate a malformed request which doesn’t contain credentials - so that path of the code never gets executed.
The server simply responds with an error response. It just so happens that this error response can contain sensitive data. 🤷♂️
Merry Christmas