MongoBleed (CVE-2025-14847) in the Logs

CVE summary

CVE-2025-14847 is a flaw in MongoDB’s zlib OP_COMPRESSED handling where mismatched size/length fields can cause the server to treat a message buffer as larger than the real decompressed payload. During BSON parsing, this can lead to reads of uninitialized heap memory and potential data exposure without authentication.


Why I’m writing this

Most write-ups focus on the vulnerability mechanics and PoC output. This article focuses on what defenders can observe in MongoDB logs when a public PoC is executed—i.e., which log patterns may help detect exploitation attempts (or at least highly suspicious malformed-wire traffic consistent with this PoC).


Lab notes (what I ran and what I changed)

  • I used the public PoC referenced here: https://github.com/joe-desimone/mongobleed/blob/main/mongobleed.py
    (the author also provides a vulnerable container; I used that container to reproduce the behavior).
  • I adjusted MongoDB logging to be as verbose as possible (debug-level output enabled) so that parsing failures and wire-protocol errors appear in the logs, not just as client-side errors.

Logging configuration used in the lab (container)

To reliably reproduce and see the full parsing/network errors in the MongoDB logs, I ran the server with a custom /etc/mongod.conf inside the container and enabled aggressive debug verbosity across components.

1) Create a high-verbosity mongod.conf

Command:

cat <<'EOF' > /etc/mongod.conf
systemLog:
  destination: file
  path: /var/log/mongodb/mongod.log
  logAppend: true

  verbosity: 5

  component:
    accessControl:
      verbosity: 5
    command:
      verbosity: 5
    control:
      verbosity: 5
    executor:
      verbosity: 5
    geo:
      verbosity: 5
    index:
      verbosity: 5
    network:
      verbosity: 5
    query:
      verbosity: 5
    replication:
      verbosity: 5
    sharding:
      verbosity: 5
    storage:
      verbosity: 5
    write:
      verbosity: 5

net:
  bindIp: 0.0.0.0
  port: 27017

processManagement:
  fork: false
EOF

2) Restart MongoDB using this config

Commands:

pkill mongod
mongod --config /etc/mongod.conf

3) Watch the logs in another shell

Command:

tail -f /var/log/mongodb/mongod.log

4) Re-run the PoC

Command:

python3 mongobleed.py --host 127.0.0.1 --port 27017

MongoDB log fields (quick)

MongoDB emits structured JSON logs with common fields:

  • t: timestamp
  • s: severity (I info, D1 debug, etc.)
  • c: component (e.g., NETWORK, COMMAND, ASSERT)
  • id: numeric message ID (stable indicator for certain log sites)
  • ctx: connection context (e.g., conn8038)
  • msg: message text
  • attr: details (error codes, error strings, remote IP, hexdumps, etc.)

For this PoC, the most relevant components are:

  • NETWORK: wire-protocol decoding / invalid message handling
  • COMMAND: parsing OP_MSG command documents
  • ASSERT: internal validation/assertion failures (often includes source file/line)

Findings (raw logs + what they mean)

Below are the exact log lines I observed after running the PoC against the vulnerable container with high verbosity logging enabled. These are highly consistent with malformed compressed OP_MSG traffic and invalid BSON parsing.

Log #1 — ASSERT / “User assertion” while reading BSON from a buffer

Log line:

{"t":{"$date":"2025-12-28T11:41:35.582+00:00"},"s":"D1","c":"ASSERT","id":23074,"ctx":"conn8038","msg":"User assertion","attr":{"error":"InvalidBSON: incorrect BSON length in element with field name 'a' in object with unknown _id","location":"src/mongo/base/data_range_cursor.h:104:16:void mongo::ConstDataRangeCursor::readAndAdvance(T*) [with T = mongo::Validated<mongo::BSONObj>]"}} 

Interpretation: MongoDB throws a user assertion (msg:"User assertion") from the ASSERT component while incrementally reading a BSON object from a buffer (mongo::ConstDataRangeCursor::readAndAdvance). The error is InvalidBSON with incorrect BSON length, pointing at element name 'a'. This is a common pattern when the server is fed malformed or intentionally inconsistent BSON.


Log #2 — NETWORK / “invalid message” + InvalidBSON + hexdump of the received payload

Log line:

{"t":{"$date":"2025-12-28T11:41:36.678+00:00"},"s":"D1","c":"NETWORK","id":22632,"ctx":"conn8138","msg":"invalid message: {ex_code} {ex} -- {hexdump_message_singleData_view2ptr_message_size}","attr":{"ex_code":22,"ex":"InvalidBSON: incorrect BSON length in element with field name 'a' in object with unknown _id","hexdump_message_singleData_view2ptr_message_size":"e1 21 00 00 01 00 00 00 00 00 00 00 dd 07 00 00 00 00 00 00 00 dd 1f 00 00 10 61 00 01 00 00 00 00 00 00 00 00 00 00 00 d0 45 93 77 33 53 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "},"truncated":{"hexdump_message_singleData_view2ptr_message_size":{"type":"string","size":26018}}}

Interpretation: MongoDB rejects an inbound message at the wire-protocol layer and logs c:"NETWORK" with a msg containing invalid message, attr.ex_code: 22 (matching InvalidBSON), exception details in attr.ex, and a large hexdump of the offending payload (truncated). This is a useful detection anchor because it’s emitted before a command fully parses.


Log #3 — COMMAND / invalid BSON type + garbage field name

Log line:

{"t":{"$date":"2025-12-28T11:41:20.385+00:00"},"s":"D1","c":"COMMAND","id":21963,"ctx":"conn6391","msg":"Assertion while parsing command","attr":{"error":"InvalidBSON: Unrecognized BSON type 192 in element with field name '8:\\u0017s_' in object with unknown _id"}}

Interpretation: The command parser hits an invalid element type byte (192) and a nonsense field name, suggesting parsing is reading misaligned/garbage bytes—typical of malformed BSON.


Log #4 — COMMAND / incorrect BSON length during command parsing

Log line:

{"t":{"$date":"2025-12-28T11:41:35.443+00:00"},"s":"D1","c":"COMMAND","id":21963,"ctx":"conn8020","msg":"Assertion while parsing command","attr":{"error":"InvalidBSON: incorrect BSON length in element with field name 'a' in object with unknown _id"}}

Interpretation: The parser again fails on an incorrect BSON length in element a, now surfaced as a command parsing assertion.


Log #5 — COMMAND / “Slow query” but actually a fast InvalidBSON failure (includes remote)

Log line:

{"t":{"$date":"2025-12-28T11:41:35.427+00:00"},"s":"I","c":"COMMAND","id":51803,"ctx":"conn8019","msg":"Slow query","attr":{"type":"none","isFromUserConnection":true,"ns":"","collectionType":"none","numYields":0,"ok":0,"errMsg":"incorrect BSON length in element with field name 'a' in object with unknown _id","errName":"InvalidBSON","errCode":22,"reslen":166,"locks":{},"cpuNanos":133975,"remote":"172.17.0.1:51408","numInterruptChecks":0,"queues":{"ingress":{},"execution":{}},"workingMillis":0,"durationMillis":0}}

Interpretation: Although the msg says Slow query, the attributes show it failed immediately (durationMillis: 0) due to InvalidBSON. The remote field is valuable for source identification.


Log #6 — ASSERT / repeated readAndAdvance assertion on a different connection

Log line:

{"t":{"$date":"2025-12-28T11:41:37.087+00:00"},"s":"D1","c":"ASSERT","id":23074,"ctx":"conn8172","msg":"User assertion","attr":{"error":"InvalidBSON: incorrect BSON length in element with field name 'a' in object with unknown _id","location":"src/mongo/base/data_range_cursor.h:104:16:void mongo::ConstDataRangeCursor::readAndAdvance(T*) [with T = mongo::Validated<mongo::BSONObj>]"}} 

Interpretation: Same assertion site as Log #1 appears again on another ctx, consistent with repeated malformed requests.


Log #7 — ASSERT / core BSON validator rejects incorrect length

Log line:

{"t":{"$date":"2025-12-28T11:41:35.458+00:00"},"s":"D1","c":"ASSERT","id":23074,"ctx":"conn8021","msg":"User assertion","attr":{"error":"InvalidBSON: incorrect BSON length","location":"src/mongo/bson/bson_validate.cpp:698:13:void mongo::{anonymous}::ValidateBuffer<precise, BSONValidator>::_validateIterative(Cursor) [with bool precise = true; BSONValidator = mongo::{anonymous}::DefaultValidator]"}} 

Interpretation: The low-level validator (bson_validate.cpp) rejects the buffer for incorrect length.


Hunting tips (useful grep commands)

These are simple, practical greps to quickly zoom in on high-signal events produced by malformed-wire / malformed-BSON traffic.

Focus on debug-level network errors

grep -E '"s":"D[12]".*"c":"NETWORK"' /var/log/mongodb/mongod.log

Narrow to likely malformed traffic keywords (BSON/invalid/malformed)

cat /var/log/mongodb/mongod.log | grep -E '"s":"D[12]".*"c":"NETWORK".*(BSON|invalid|malformed)'

Broad search for BSON parsing failures

cat /var/log/mongodb/mongod.log | grep "BSON"

What to Alert On

If you’re building detections from MongoDB logs alone, the most useful signals are the combination of:

  • c:"NETWORK" + msg contains invalid message + attr.ex_code: 22 and/or attr.ex contains InvalidBSON
  • c:"COMMAND" + msg:"Assertion while parsing command" + (incorrect BSON length or Unrecognized BSON type)
  • c:"ASSERT" + msg:"User assertion" + locations like:
    • src/mongo/base/data_range_cursor.h
    • src/mongo/bson/bson_validate.cpp
  • bursts across multiple ctx values and/or repeated remote values

No single line proves memory disclosure occurred, but these patterns strongly indicate malformed-wire / malformed-BSON traffic consistent with probing or exploitation attempts.


Disclaimer

This is experimental, based on a controlled reproduction using a public PoC and a vulnerable demo container, with logging turned up to maximum verbosity. These patterns strongly correlate with malformed BSON / malformed-wire traffic, but they are not proof of successful memory disclosure by themselves and can overlap with fuzzing or buggy-client scenarios.


References

  • https://github.com/joe-desimone/mongobleed/tree/main
  • https://bigdata.2minutestreaming.com/p/mongobleed-explained-simply
  • https://blog.ecapuano.com/p/hunting-mongobleed-cve-2025-14847
  • https://doublepulsar.com/merry-christmas-day-have-a-mongodb-security-incident-9537f54289eb
  • https://www.mongodb.com/docs/manual/reference/log-messages/#std-label-log-message-components