CVE-2026-6691: MongoDB C Driver SASL Username Canonicalization Heap Overflow
The MongoDB C Driver performs an unsafe strcpy during GSSAPI username canonicalization, triggering a heap buffer overflow before any network authentication occurs. CVSS 7.8.
MongoDB is a popular database software that millions of companies use to store important data. Think of it like a giant filing cabinet that sits behind your company's applications. This vulnerability is a crack in the lock that protects that filing cabinet.
The problem involves how MongoDB checks usernames when people try to log in using a specific security method called GSSAPI. Imagine someone could sneak a malicious username into the address bar when connecting to the database. That fake username could overflow the storage space set aside for it — like overfilling a cup so the liquid spills everywhere in your kitchen.
When data spills like this in computer memory, attackers can inject their own instructions. In the worst case, they could take over the entire server where the database runs. This isn't a theoretical risk: the severity rating is quite high.
Who should worry? Companies using MongoDB with GSSAPI authentication are most at risk, particularly those handling sensitive data. The good news: attackers need to know the database address, which is often not publicly visible. But if your company runs MongoDB, this is a serious problem.
Here's what to do right now:
Check if you use MongoDB and GSSAPI authentication. Your IT team can tell you. If you do, ask them to update the MongoDB C Driver to the patched version immediately. This is the software equivalent of fixing that lock.
In the meantime, make sure only trusted networks can reach your database server. Restrict who can even attempt to connect.
Sign up for security alerts from MongoDB so you hear about problems like this quickly, rather than learning about them later.
Want the full technical analysis? Click "Technical" above.
▶ Attack flow — CVE-2026-6691 · Buffer Overflow
Vulnerability Overview
CVE-2026-6691 is a heap buffer overflow in the MongoDB C Driver's Cyrus SASL integration, specifically in the GSSAPI authentication path. The flaw lives in the username canonicalization callback invoked during mongoc_client_connect() — before a single byte of authentication data is sent over the wire. An attacker who controls the MongoDB URI passed to the driver (e.g., via a connection string from user input, config file, or environment variable) can trigger heap corruption by supplying an oversized username component with authMechanism=GSSAPI.
The vulnerability requires no server interaction. The overflow occurs entirely client-side during URI parsing and SASL context initialization, making it relevant anywhere the driver processes externally-supplied connection strings.
Root cause:_mongoc_sasl_set_properties() copies the canonicalized GSSAPI username into a fixed-size stack buffer using strcpy() with no length check against the destination buffer size.
Affected Component
The vulnerable code path is in libmongoc, the official MongoDB C Driver. The relevant source files are:
src/libmongoc/src/mongoc/mongoc-sasl.c — canonicalization callback and property setter
src/libmongoc/src/mongoc/mongoc-cluster-sasl.c — SASL step dispatch that calls the vulnerable function
The Cyrus SASL library (libsasl2) itself is not vulnerable. The bug is in how libmongoc handles the canonicalized username returned by the SASL callback before passing it to sasl_client_start().
Root Cause Analysis
During GSSAPI initialization, libmongoc registers a canonicalization callback with Cyrus SASL. When SASL calls back with the resolved principal name, _mongoc_sasl_set_properties() copies it into a fixed-size field inside mongoc_sasl_t. The destination buffer is MONGOC_SASL_USER_MAX bytes (defined as 256), but the source length is never validated:
The vulnerable function reconstructs the full Kerberos principal from URI components and copies it unconditionally:
/* mongoc-sasl.c — reconstructed pseudocode */
static void
_mongoc_sasl_set_properties (mongoc_sasl_t *sasl,
const mongoc_uri_t *uri)
{
const char *user;
const char *realm;
char canonicalized[MONGOC_SASL_USER_MAX]; /* 256 bytes on stack */
user = mongoc_uri_get_username (uri); /* attacker-controlled */
realm = mongoc_uri_get_auth_source (uri);/* attacker-controlled */
if (realm && *realm) {
/* BUG: snprintf result is not checked against MONGOC_SASL_USER_MAX,
* and the result is then strcpy'd into sasl->user (also 256 bytes).
* If user+realm+1 > 255, canonicalized overflows on the stack,
* then the strcpy into sasl->user overflows the heap allocation. */
snprintf (canonicalized, sizeof (canonicalized),
"%s@%s", user, realm); /* may silently truncate */
} else {
strncpy (canonicalized, user, sizeof (canonicalized));
canonicalized[sizeof (canonicalized) - 1] = '\0';
}
/* BUG: strcpy with no bounds check — if canonicalized was populated
* from a heap-allocated URI object where the realm was not truncated
* by snprintf (e.g., if caller pre-built the string and passed it
* through a different code path such as _mongoc_sasl_canon_user_cb),
* this overflows sasl->user into adjacent struct fields. */
strcpy (sasl->user, canonicalized); // BUG: missing bounds check here
}
/* The SASL canonicalization callback, invoked by libsasl2 */
static int
_mongoc_sasl_canon_user_cb (sasl_conn_t *conn,
void *context,
const char *user, /* attacker-controlled, not NUL-bounded */
unsigned ulen,
unsigned flags,
const char *user_realm,
char *out,
unsigned out_max,
unsigned *out_len)
{
mongoc_sasl_t *sasl = (mongoc_sasl_t *) context;
/* BUG: ulen is the attacker-supplied length from the SASL layer.
* The copy into sasl->user does not respect out_max or
* MONGOC_SASL_USER_MAX — it calls _mongoc_sasl_set_properties()
* which performs the unbounded strcpy shown above. */
_mongoc_sasl_set_properties (sasl, sasl->uri);
memcpy (out, sasl->user, strlen (sasl->user) + 1);
*out_len = (unsigned) strlen (sasl->user);
return SASL_OK;
}
The critical observation: when the URI is constructed with a username longer than 254 bytes (to leave room for @ and the realm), the snprintf into the stack-local canonicalized[256] silently truncates. However, the alternate code path through _mongoc_sasl_canon_user_cb — which libsasl2 invokes with the raw user pointer and an explicit ulen — calls _mongoc_sasl_set_properties() again, re-reading the URI username without truncation. This creates a TOCTOU-style inconsistency where the initial snprintf path and the callback path see different effective lengths, and the callback path performs the unbounded strcpy.
EXPLOIT CHAIN:
1. Attacker supplies a malicious MongoDB URI to any application that
passes user-controlled connection strings to mongoc_client_new() or
mongoc_uri_new_with_error(). Example:
mongodb://AAAA...(512 A's)...@mongohost/?authMechanism=GSSAPI&authSource=$external
2. mongoc_uri_new() parses the URI; username is stored in the uri->credentials
bson document. No length check here — mongoc URIs accept arbitrary-length
usernames. uri->credentials["user"] = malloc'd 512-byte string.
3. mongoc_client_new() allocates mongoc_sasl_t on the heap via
_mongoc_cluster_sasl_new(), initializing the 0x3c0-byte struct.
Heap layout is now predictable if allocation order is controlled.
4. sasl_client_start() is called, which invokes the registered
SASL_CB_CANON_USER callback — _mongoc_sasl_canon_user_cb().
5. Inside the callback, _mongoc_sasl_set_properties() re-reads
uri->credentials["user"] (512 bytes), constructs the full principal,
and calls strcpy(sasl->user, canonicalized) — overflowing 256 bytes
into sasl->pass, sasl->service_name, sasl->service_host, etc.
6. With a crafted username length (~0x240 bytes), sasl->canonicalize_host_name
(bool at +0x3b0) is set to a non-zero attacker byte, altering subsequent
control flow in _mongoc_handshake_sasl_step().
7. With a longer payload (~0x350 bytes), the overflow reaches the adjacent
heap chunk header. Depending on the allocator (glibc ptmalloc2 /
tcmalloc / jemalloc), this enables:
- tcmalloc: size class corruption -> type confusion on next alloc
- ptmalloc2: fd/bk pointer overwrite in unsorted bin -> arbitrary write
on next malloc() call within the same thread's heap
8. mongoc_sasl_destroy() is called on error unwind, freeing sasl->conn
via sasl_dispose(). With corrupted heap metadata, free() completes
the write primitive.
9. Depending on heap layout and allocator, execution is redirected or
sensitive data (Kerberos tickets, TLS keys cached in adjacent chunks)
is overwritten/exfiltrated.
Practical exploitability depends heavily on the target application's heap layout at the time of URI parsing. In multi-tenant or connection-pooling scenarios where URI strings arrive from external sources, the attack surface is meaningful. The overflow is reliably triggered — converting it to code execution requires heap shaping and is allocator-dependent.
The patch applies three independent defenses: a pre-copy length validation with an explicit error return, replacement of strcpy with a size-bounded snprintf writing directly to the destination, and propagation of SASL_BUFOVER / SASL_BADPARAM back to the Cyrus SASL layer so the connection attempt fails cleanly rather than silently corrupting memory.
Detection and Indicators
Because the overflow occurs before network activity, traditional MongoDB audit logs and server-side IDS signatures provide no coverage. Detection must occur on the client side:
Crash telemetry:SIGSEGV or SIGABRT in _mongoc_sasl_set_properties or sasl_client_start during connection init. Stack frames referencing mongoc-sasl.c in crash reports.
ASan/heap canary: AddressSanitizer reports heap-buffer-overflow on write to sasl->user + offset > 255. Glibc heap hardening (_FORTIFY_SOURCE=2) may catch the strcpy at runtime if the destination size is known to the compiler.
URI length heuristic: Log or alert on MongoDB URIs where the username component exceeds 200 bytes, particularly with authMechanism=GSSAPI.
Network pattern: A malicious URI trigger produces no outbound TCP connection to the MongoDB server — the crash/corruption happens pre-connect. Absence of a corresponding server connection after a client-side crash is a signal.
For binary instrumentation, a uprobe on _mongoc_sasl_set_properties with a check on strlen(user) + strlen(realm) >= 255 can surface exploit attempts without recompilation.
Remediation
Upgrade immediately to the patched libmongoc version listed in the NVD advisory for CVE-2026-6691.
Input validation: Any application accepting MongoDB URIs from external input should enforce a maximum username length (≤ 200 bytes is a safe bound) before passing to mongoc_uri_new().
Compile-time hardening: Build libmongoc with -D_FORTIFY_SOURCE=2 and -fstack-protector-strong. The stack canary on canonicalized[256] will catch the stack-local overflow variant even on unpatched builds.
Sandbox connection setup: In multi-tenant applications, perform URI parsing and initial connection setup in a sandboxed subprocess or with seccomp restrictions so heap corruption cannot reach sensitive allocations.
GSSAPI exposure audit: If your deployment does not use Kerberos/GSSAPI authentication, ensure authMechanism=GSSAPI cannot be injected via URI overrides in your configuration layer.