A BSON symbol namespace bypasses MongoDB's authorization check (CVE-2026-18690)

slvnx1 pts0 comments

MongoDB Symbol-Type Authorization Bypass (CVE-2026-18690): Limited User Reaches System Collections — RECON Research

Professional network intelligence for the field. 18 instrument modules — ping, traceroute, DNS, port scan, WHOIS, TLS, LAN sweep, throughput — in one tactical iOS workspace.

Designed for security/IR teams, military NetOps, network engineers and sysadmins.

AUGUST 12, 2026CVSS 8.1 · AUTHZ BYPASS · 4 CVES13 MIN READ<br>MongoDB's Symbol-Type Authorization Bypass (CVE-2026-18690): When the Auth Check and the Command Disagree About the Target<br>On August 11, 2026 MongoDB disclosed four Server vulnerabilities, all fixed in the same 8.0.29 / 7.0.40 / 8.3.8 releases. The one worth reading closely, CVE-2026-18690, is a small, exact bug with a familiar shape: a database command carries the name of the collection it targets, and MongoDB parses that name twice — once to authorize the request and once to execute it. If the name is sent as a BSON symbol instead of a string, the authorization parse silently collapses to a database-level namespace while execution still resolves the real collection. The two halves of the server disagree about what is being touched, and a low-privileged user reaches a protected system collection the authorization check would otherwise refuse. We reverse-engineered the exact vector from MongoDB's own one-line source fix and reproduced it against a real MongoDB 8.0.28, with the fix verified on 8.0.29.<br>DISCLOSURE: four MongoDB Server CVEs published August 11, 2026 (CVE-2026-18690, -18691, -18692, -18712), all fixed in 8.0.29 / 7.0.40 / 8.3.8<br>HEADLINE: CVE-2026-18690 — CWE-863 Incorrect Authorization; a symbol-typed collection name bypasses the authorization check on protected system collections. CVSS 3.1 8.1 (CVSS 4.0 7.2), vector C:N/I:H/A:H — integrity and availability, not disclosure<br>HIGHEST SCORE: CVE-2026-18691 — CVSS 4.0 9.0 Critical (3.1: 8.8), an intra-cluster authentication-mechanism downgrade (CWE-757) that can expose the replica set's internal credential<br>THREAT MODEL: PR:L — the attacker already holds a valid, limited MongoDB account (a database-scoped role). This is privilege escalation inside an authenticated deployment, not an unauthenticated internet-facing bug<br>EXPLOITED: no public evidence of in-the-wild exploitation; not CISA KEV-listed as of writing<br>SOURCE: MongoDB Inc. is the CNA; scores are MongoDB's own (dual CVSS 3.1 and 4.0). Root cause traced to SERVER-130481

AM I EXPOSED?<br>AFFECTEDMongoDB Server below 7.0.40 / 8.0.29 / 8.3.8 (the 8.3 line also carries the -18692 timeseries bug) and at least one user holds a limited, database-scoped role rather than full admin.<br>NOT YOUDeployments where every account is a full administrator (nothing to escalate from), or anything already on 7.0.40+ / 8.0.29+ / 8.3.8+.<br>CHECKmongosh "$URI" --quiet --eval 'db.version()' — compare against 7.0.40 / 8.0.29 / 8.3.8. Locally: mongod --version.<br>FIXUpgrade to the fixed patch release for your line (7.0.40, 8.0.29, or 8.3.8). There is no configuration workaround — the parser fix is the remedy.

The Pattern: Two Parses, One Namespace<br>MongoDB enforces role-based access control on every command. A command names the collection it operates on — { convertToCapped: "orders", size: 4096 } — and the server extracts that namespace to decide two separate things: may this user do this? (authorization) and what exactly do I do? (execution). The security model holds only if both halves extract the same namespace from the same command. When they diverge, the authorization check is answering a question about a different object than the one the command will actually touch.<br>That is exactly the shape of the Portainer authorization bypass we covered — there, a request the proxy did not canonicalize reached the Docker daemon around the check. Here the split is finer: it lives inside a single MongoDB process, in the handful of lines that read the collection name out of a command's BSON.<br>Root Cause: A Non-String Namespace Falls Back to the Database<br>MongoDB's namespace extraction for a command lives in CommandHelpers::parseNsFromCommand. The vulnerable version reads the command's first field — the collection name — and if it is not a String, gives up and returns a namespace containing only the database:<br>// src/mongo/db/commands.cpp (MongoDB 8.0.28, vulnerable)<br>NamespaceString CommandHelpers::parseNsFromCommand(const DatabaseName& dbName,<br>const BSONObj& cmdObj) {<br>BSONElement first = cmdObj.firstElement();<br>if (first.type() != mongo::String) // a BSON 'symbol' is not a String...<br>return NamespaceString(dbName); // ...so this returns a DATABASE-ONLY namespace<br>return NamespaceStringUtil::deserialize(dbName, first.valueStringData());<br>}A BSON symbol (type 0x0E) is a deprecated string-like type: on the wire it stores its text exactly like a string, but its type byte is different. So when the collection name arrives as a symbol, this function's type() != String test is true, and it returns a database-only namespace. The...

mongodb namespace authorization command symbol database

Related Articles