Jan 28, 2026·7 min read·15 visits
RethinkDB's internal JSON parser has a critical RCE flaw. A specific Unicode escape sequence can trick the parser into writing past its allocated buffer. CVSS 10.0.
A critical heap-based buffer overflow in RethinkDB's cJSON parsing logic allows remote attackers to execute arbitrary code. The vulnerability stems from a discrepancy between the memory allocation pass and the string copying pass within the `parse_string` function. By supplying a malformed JSON string with a truncated Unicode escape sequence, an attacker can trick the parser into jumping over the terminating quote, causing it to copy heap data into a finite buffer indefinitely.
RethinkDB pitched itself as the open-source database for the real-time web, a MongoDB killer that pushed JSON to your clients faster than you could say "eventual consistency." But as it turns out, in its haste to process your documents, it forgot one of the cardinal rules of C programming: if you're going to manually manage memory, you better be damn sure your math is perfect.
At the heart of this catastrophe is cJSON, a lightweight C library used for—you guessed it—parsing JSON. It's fast, it's simple, and in this specific implementation, it's fatally flawed. We aren't looking at a complex logic bug buried deep in the replication protocol. We are looking at a classic, 1990s-style heap corruption triggered by a string that looks a bit weird.
CVE-2026-24810 isn't just a Denial of Service (though it does that beautifully). It's a full-blown Remote Code Execution (RCE) vector because the overflow happens on the heap, adjacent to function pointers and vtables that, when clobbered, hand over the keys to the kingdom. It is a stark reminder that even modern databases are often just one while loop away from disaster.
To understand why this breaks, you have to understand how cJSON handles strings. It uses a "Two-Pass" approach. In C, you can't just resize arrays on the fly efficiently, so the code does this:
malloc(length + 1) based on that count.\n or \u0041) and writing the final bytes into the new memory.The vulnerability is a desynchronization between the Surveyor and the Carpenter. The Surveyor assumes valid input. The Carpenter, however, gets confident. When processing a Unicode escape sequence (e.g., \uXXXX), the code manually advances the input pointer by 4 bytes to skip the hex digits.
Here is the punchline: The code never checked if those 4 bytes actually existed before advancing. If you end your string with "\u" (and no hex digits), the pointer addition jumps over the closing quote of the string. The loop condition while (*ptr != '"') never sees the end of the string because we just vaulted right past it. The parser blindly continues into adjacent heap memory, treating whatever garbage it finds as part of the string, and writing it into a buffer that is now far too small.
Let's look at the smoking gun in src/cjson/cJSON.cc. This is a textbook example of why pointer arithmetic is dangerous.
The Vulnerable Logic:
// Pass 2: The Loop
while (*ptr != '\"' && *ptr) {
if (*ptr != '\\') {
*ptr2++ = *ptr++;
} else {
ptr++; // Skip the backslash
switch (*ptr) {
// ... other cases ...
case 'u':
// DANGER ZONE
uc = parse_hex4(ptr+1);
ptr += 4; // <--- The Blind Jump
// ... encoding logic ...
break;
}
}
}See that ptr += 4? It assumes there are 4 characters to skip. If the input is "fail\u", the pointer is currently at u. ptr += 4 pushes it past the closing quote. The loop continues, reading memory until it randomly hits a quote character or crashes.
The Fix (PR #7163):
The developers had to introduce a hard stop. They calculated end_ptr during the first pass and forced the second pass to respect it.
// The patched loop condition
while (ptr < end_ptr) { // <--- strict boundary check
// ...
case 'u':
uc = parse_hex4(ptr+1);
ptr += 4;
// The Safety Net
if (ptr >= end_ptr) {
return 0; // Bail out if we jumped too far
}
break;
}This simple check prevents the pointer from running off into the sunset (and your heap metadata).
Exploiting this requires finesse. We aren't just crashing the server; we want to control it. The goal is to groom the heap so that interesting objects lie immediately after our malicious string.
The Attack Chain:
{"hax": "AAAAAAAA\u"}. Note the trailing \u without digits.\u.ptr by 4 bytes, skipping the closing " and landing in the next chunk of memory.ptr2).By carefully crafting the data that lies after the quote (in the next chunk), or simply letting the copy run until it hits a naturally occurring quote, we overwrite the metadata of the next allocated object. When RethinkDB tries to use that object (e.g., calling a virtual destructor), it jumps to an address we control. Game over.
This is a CVSS 10.0 for a reason. RethinkDB is often exposed to internal microservices or, God forbid, the public internet (don't do that).
Availability (DoS): Trivial. Sending a single malformed packet crashes the server instantly due to a segmentation fault when the reader hits unmapped memory.
Integrity & Confidentiality (RCE): High. A skilled attacker can turn this memory corruption into arbitrary code execution. Once inside, they have full access to the data stored in the DB, can modify records, or pivot to the underlying OS. Since the database often runs with significant privileges to manage files and network sockets, the blast radius is the entire server.
This affects all versions up to v2.4.4. If you are running an older RethinkDB instance, you are sitting on a powder keg.
If you are running RethinkDB, stop reading and check your version. If it is 2.4.4 or older, you are vulnerable.
Remediation Steps:
\u at the end of a string).This vulnerability is a harsh lesson in legacy C code maintenance. Always validate your boundaries, especially when your loop involves pointer arithmetic.
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/S:N/AU:Y/R:U/V:C/RE:M/U:Red| Product | Affected Versions | Fixed Version |
|---|---|---|
RethinkDB RethinkDB | <= 2.4.4 | Post-v2.4.4 (See PR #7163) |
| Attribute | Detail |
|---|---|
| CWE | CWE-120 (Buffer Copy without Checking Size of Input) |
| CVSS v4.0 | 10.0 (Critical) |
| Attack Vector | Network (Remote) |
| Impact | Remote Code Execution (RCE) / Denial of Service |
| Affected Component | src/cjson/cJSON.cc (parse_string) |
| Exploit Status | Proof of Concept likely achievable |
Buffer Copy without Checking Size of Input ('Classic Buffer Overflow')