-
Type:
Bug
-
Resolution: Fixed
-
Priority:
Major - P3
-
Affects Version/s: None
-
Component/s: None
-
None
-
0.2
-
Dotnet Drivers
-
Not Needed
-
None
-
None
-
None
-
None
-
None
-
None
Summary
Windows apps using auto-encryption with a non-ASCII database name silently send fields meant to be encrypted to the server in plaintext.
Impact
Fields the customer configured to be encrypted before leaving the client are silently persisted in plaintext on the MongoDB server, defeating the CSFLE/QE confidentiality boundary against server operators, backups, and database breaches.
Severity: high (upper bound critical)
Exploitability: likely_exploitable — Manifests deterministically whenever the three deployment conditions hold; no attacker action is needed for the exposure, and a tenant who influences database naming can trigger it on demand.
Customer data: pii, phi, pci, customer_content (third_party)
Location
- src/MongoDB.Driver.Encryption/CryptClient.cs:80 in CryptClient.StartEncryptionContext
- src/MongoDB.Driver.Encryption/CryptClient.cs:92 in CryptClient.StartEncryptionContext
- src/MongoDB.Driver.Encryption/AutoEncryptionLibMongoController.cs:113 in AutoEncryptionLibMongoController.EncryptFields
- src/MongoDB.Driver.Encryption/AutoEncryptionLibMongoController.cs:181 in AutoEncryptionLibMongoController.ProcessNeedCollectionInfoState
- src/MongoDB.Driver.Encryption/AutoEncryptionLibMongoController.cs:213 in AutoEncryptionLibMongoController.ProcessNeedMongoMarkingsState
- src/MongoDB.Driver/Core/DatabaseNamespace.cs:54 in DatabaseNamespace.IsValid
Reproduction / trigger path
Analyzed trigger path from static analysis — not an executed PoC. Confirm with a concrete repro before handing off.
Attacker controls: The trigger value is the application-chosen database name (tenant-derived in many SaaS designs); the exposed data is every field designated for client-side encryption in commands run against that database. Best-fit ANSI mapping can also collapse distinct Unicode names onto one mangled string, confusing schema selection across namespaces.
- (source) src/MongoDB.Driver/Core/WireProtocol/CommandUsingCommandMessageWireProtocol.cs:239 in AutoEncryptFieldsIfNecessary — Every auto-encrypted operation forwards the application's database name (only '.'/NUL/empty rejected by DatabaseNamespace.IsValid) into the encryption pipeline.
- (hop) src/MongoDB.Driver/Core/WireProtocol/CommandMessageFieldEncryptor.cs:48 in CommandMessageFieldEncryptor.EncryptFields — Serializes the command and passes the untouched database name to the encryption controller.
- (hop) src/MongoDB.Driver.Encryption/AutoEncryptionLibMongoController.cs:113 in AutoEncryptionLibMongoController.EncryptFields — Forwards the name unmodified into StartEncryptionContext (async twin at line 128).
- (sink) src/MongoDB.Driver.Encryption/CryptClient.cs:80 in CryptClient.StartEncryptionContext — StringToHGlobalAnsi lossy-converts the name on Windows; line 92 initializes the native context with the mangled name (strlen, length -1), so schema-map/encrypted-fields-map lookups miss and the command exits unencrypted.
- (hop) src/MongoDB.Driver.Encryption/AutoEncryptionLibMongoController.cs:181 in ProcessNeedCollectionInfoState — Divergence: collection-info (and mongocryptd at line 213) queries run under the original correct name, so the mismatch never produces an error — the failure is silent.
Root cause
- src/MongoDB.Driver.Encryption/CryptClient.cs:80 — `Marshal.StringToHGlobalAnsi(db)` converts the UTF-16 database name via the system ANSI code page on Windows, silently best-fitting/replacing characters that MongoDB namespaces (UTF-8) legally contain.
- src/MongoDB.Driver.Encryption/CryptClient.cs:92 — the mangled pointer is handed to `mongocrypt_ctx_encrypt_init` with length -1, so libmongocrypt adopts the corrupted name for all schema-map and encrypted-fields-map namespace matching; the maps themselves were delivered as correct UTF-8 BSON (src/MongoDB.Driver.Encryption/CryptClientFactory.cs:67-75,147), so lookups miss and the command passes through unencrypted.
- src/MongoDB.Driver.Encryption/AutoEncryptionLibMongoController.cs:181 and :213 — the collection-info and mongocryptd queries run under the original, uncorrupted name, so the two halves of the pipeline disagree and no error surfaces.
- src/MongoDB.Driver/Core/DatabaseNamespace.cs:47-56 — the only database-name validation rejects just empty names, '.', and NUL; non-ASCII names flow through src/MongoDB.Driver/Core/WireProtocol/CommandUsingCommandMessageWireProtocol.cs:239 and CommandMessageFieldEncryptor.cs:48 into the sink unmodified.
Ownership
Assigned teams: @mongodb/dbx-csharp-dotnet
Filed from Aegis finding 85e217525ec8 (scan scan-dddfc7fea86a) · primitive: Silent fail-open of client-side field encryption: lossy ANSI conversion of the database name breaks schema-map matching, so designated fields ship plaintext. · categories: PII Exposure, Silent Data Truncation, Data Corruption