87,000 internet-exposed MongoDB servers. Zero authentication required. One malformed packet — and you’re reading heap memory that was never meant to leave the server.
That’s MongoBleed. CVE-2025-14847 dropped in December 2025 with a public PoC less than two weeks after the patch. CISA added it to the KEV catalog within ten days of disclosure. This isn’t a theoretical bug — Wiz telemetry found that 42% of visible MongoDB deployments were running a vulnerable version, and threat actors were already claiming credit for real-world breaches before most teams had even read the advisory.
This post is a technical walkthrough of how MongoBleed works from the wire up: the vulnerability root cause, exactly how to craft the malicious packet, what the heap spills, and how to detect it if you’re defending.
What Is MongoBleed?
MongoBleed is a pre-authentication memory disclosure vulnerability in MongoDB’s zlib network compression implementation. By sending a specially crafted compressed packet with a mismatched length field, an unauthenticated remote attacker can cause MongoDB to return uninitialized heap memory in its error response — heap memory that may contain database passwords, AWS secret keys, session tokens, and arbitrary in-memory BSON documents.
| Field | Value |
|---|---|
| CVE | CVE-2025-14847 |
| CVSS 4.0 | 8.7 HIGH |
| CVSS 3.1 | 7.5 HIGH |
| CWE | CWE-130 — Improper Handling of Length Parameter Inconsistency |
| Auth required | None |
| Network access | Remote |
| User interaction | None |
| CISA KEV | Yes — remediation due January 19, 2026 |
| Discovered by | Joe Desimone (Elastic) |
The name is a nod to Heartbleed — same class of bug: you ask for more data than exists, and the server gives you memory it shouldn’t. The mechanic here is MongoDB’s zlib decompression layer returning the size of the allocated buffer rather than the size of the decompressed data. That off-by-design flaw turns every oversized allocation into a window into heap memory.
Affected Versions
| Branch | Vulnerable Range | Fixed Version |
|---|---|---|
| 8.2 | 8.2.0 – 8.2.2 | 8.2.3 |
| 8.0 | 8.0.0 – 8.0.16 | 8.0.17 |
| 7.0 | 7.0.0 – 7.0.27 | 7.0.28 |
| 6.0 | 6.0.0 – 6.0.26 | 6.0.27 |
| 5.0 | 5.0.0 – 5.0.31 | 5.0.32 |
| 4.4 | 4.4.0 – 4.4.29 | 4.4.30 |
| 4.2 / 4.0 / 3.6 | All versions | No fix — EOL |
If you’re running 4.2 or older, there’s no patch coming. Your only option is to disable zlib compression or migrate.
The Root Cause: A Length Field Lies
MongoDB’s wire protocol supports network-level compression via OP_COMPRESSED (opcode 2012). When compression is enabled — and zlib is the default in most deployments — every message on the wire goes through this path.
The structure of an OP_COMPRESSED message looks like this:
|
|
The uncompressed_size field is meant to tell the server how large a buffer to allocate before decompressing. The server trusts this value completely.
When MongoDB decompresses the message, it:
- Reads
uncompressed_sizeand allocates a buffer of that size - Decompresses the zlib payload into that buffer
- Returns
uncompressed_size(the claimed size) as the message length — not the actual number of bytes written by zlib
Step 3 is the bug. If uncompressed_size is larger than the actual decompressed data, MongoDB treats the tail of the allocation — uninitialized heap memory — as part of the message. When the oversized “message” fails BSON parsing, the server generates an error response that contains fragments of that uninitialized buffer.
You’re not overflowing anything. You’re not corrupting memory. You’re just asking nicely for more than exists, and MongoDB hands it over.
Building the Exploit
The exploit is about 60 lines of Python. Here’s the full mechanics:
Step 1 — Craft a Minimal BSON Document
You need a valid but small BSON payload. The goal is to create a tiny compressed message so that when you lie about uncompressed_size, the gap between real data and claimed size is large — maximizing heap exposure.
|
|
Step 2 — Wrap in OP_MSG
OP_MSG (opcode 2013) is MongoDB’s standard query/command framing. A section type 0x00 means “body” — a single BSON document.
|
|
Step 3 — Compress and Lie About the Size
This is where the bug lives. You compress the real message, then claim in uncompressed_size that the message is much larger.
|
|
The +500 offset is tunable. Larger values leak more memory per request; too large and the server may reject the packet at a different check. In practice, offsets between 200 and 2000 bytes produce reliable leaks.
Step 4 — Build the Full OP_COMPRESSED Packet
|
|
Step 5 — Send and Extract
Send the packet over raw TCP (port 27017) and parse the error response for leaked memory fragments:
|
|
Note: I’ll be adding lab screenshots here demonstrating the exploit running against a vulnerable MongoDB instance and the heap data extracted from the responses.
What Comes Out of the Heap
The heap of a running MongoDB process is a goldmine. Depending on what your target is doing, you can pull:
Credentials and Secrets
- Plaintext database passwords from authentication operations that haven’t been GC’d yet
- AWS access keys (format
AKIA...) from config loaded at startup or stored in a collection - API tokens and bearer tokens from application sessions
BSON Document Fragments
- Field names and partial values from recently processed queries
- Collection names, index names, and schema metadata
Internal MongoDB State
- Connection strings with embedded credentials
- Replication set configuration with hostnames and auth info
- GridFS metadata
The exploit doesn’t give you a clean dump — you’re reading heap through a keyhole. But across 50–100 requests, the fragments accumulate. The researchers who found active exploitation in the wild reported pulling AWS secret keys and plaintext passwords from production instances in under two minutes.
Lab output screenshots will be inserted here — showing real heap extractions from a controlled test environment.
Exploitation in the Wild
The timeline moved fast:
- Dec 19, 2025 — MongoDB releases patches across all supported branches
- Dec 25–28, 2025 — Public PoC released on GitHub by Elastic researcher Joe Desimone
- Dec 27, 2025 — Censys reports 87,000+ exposed instances; active exploitation confirmed in the wild
- Dec 29, 2025 — CISA adds CVE-2025-14847 to KEV catalog, mandating federal remediation by Jan 19, 2026
Geographic breakdown of exposed instances at peak:
- 🇺🇸 United States: ~20,000
- 🇨🇳 China: ~17,000
- 🇩🇪 Germany: ~8,000
The Ubisoft Rainbow Six Siege breach that surfaced in late December 2025 had unverified claims linking it to MongoBleed — no confirmed attribution, but the timing lines up with active exploitation.
Detection
The Behavioral Tell: No Client Metadata
Every legitimate MongoDB driver — PyMongo, the Node.js driver, mongosh, the Java driver — sends a client metadata document immediately after connecting. MongoDB logs this as event 51800. The MongoBleed exploit never does this. It connects, fires malformed packets, and disconnects.
That single signal is your best detection: a source IP with high connection volume and zero metadata events.
Key log event IDs to monitor:
| Event ID | Meaning |
|---|---|
| 22943 | Connection established |
| 51800 | Client metadata received (legitimate drivers) |
| 22944 | Connection closed |
Risk scoring thresholds (from Eric Capuano’s detection research):
| Risk | Condition |
|---|---|
| 🔴 HIGH | ≥100 connections + <10% metadata rate + ≥500 conn/min |
| 🟡 MEDIUM | ≥100 connections + <10% metadata rate (lower velocity) |
| 🟢 LOW | ≥100 connections (normal metadata rate) |
In lab testing, the public PoC produced 499 connections in 0.3 seconds with a 0% metadata rate — versus legitimate traffic at 0.2–3.2 connections/minute with 99–100% metadata rate. That’s a 3–5 order of magnitude difference. You can’t miss it.
MongoDB Log Query (jq)
If you’re on MongoDB 4.4+ with JSON-structured logs:
|
|
Velociraptor Hunt Artifact
Eric Capuano released a Velociraptor artifact (Linux.Detection.CVE202514847.MongoBleed) that automates this analysis against both native and Docker MongoDB logs. It’s tunable with thresholds for time window, connection count, and velocity — and outputs per-IP risk scores. Highly recommended if you’re doing incident response at scale.
Network-Level Signature
The malicious packet has a predictable structure: OP_COMPRESSED (opcode 0x7DC) wrapping OP_MSG (opcode 0x7DD) with compressor_id = 2 (zlib), where uncompressed_size significantly exceeds the actual decompressed payload. A Suricata or Zeek rule targeting this mismatch on port 27017 can catch it at the perimeter.
Remediation
Patch — Preferred
Update to a fixed version. If you’re on an unsupported branch (4.2, 4.0, 3.6), these are EOL and will never receive a patch — migrate now.
| Branch | Target Version |
|---|---|
| 8.2 | ≥ 8.2.3 |
| 8.0 | ≥ 8.0.17 |
| 7.0 | ≥ 7.0.28 |
| 6.0 | ≥ 6.0.27 |
| 5.0 | ≥ 5.0.32 |
| 4.4 | ≥ 4.4.30 |
Disable zlib Compression — If You Can’t Patch Immediately
In mongod.conf:
|
|
Or via command line: --networkMessageCompressors snappy
This removes the vulnerable code path entirely. Note that removing zlib will affect compression ratios for high-throughput workloads — snappy is faster but compresses less aggressively.
Lock Down Network Access
MongoDB should never be reachable from the public internet. If yours is:
|
|
Add firewall rules. Restrict port 27017 to trusted application servers only. This doesn’t fix the vulnerability but eliminates the attack surface for the 87,000 servers currently exposed.
Enable Audit Logging
If you’re not already logging connections, start now:
|
|
This gives you the event 51800 data you need for detection.
Takeaways
- Patch immediately. MongoBleed is in CISA KEV, actively exploited, and has a public PoC. There’s no ambiguity here.
- MongoDB should not be internet-facing. Of the 87,000 exposed instances, most have no legitimate reason to be reachable on port 27017 from the public internet. Fix your security groups and firewall rules regardless of patch status.
- Disable zlib if patching is delayed. Switching
networkMessageCompressorstosnappyremoves the vulnerable code path with minimal operational impact. - Hunt for exploitation now. If you run MongoDB and haven’t checked your logs for the anomalous connection patterns described above — particularly pre-patch-date traffic — do it today. Memory disclosure leaves no obvious data corruption footprint; you won’t find it without looking at connection metadata rates.
Lab environment screenshots demonstrating the exploitation steps and heap extraction output will be added to this post.
Sources: NVD · MongoDB Advisory · BleepingComputer · OX Security PoC Walkthrough · Eric Capuano — Hunting MongoBleed · Tenable · Aikido