flawopen.com/Teardowns/langchain-mongodb-chat-history-query-injection-cve-2026-106119
CVE-2026-106119: LangChain MongoDB Session Query Injection
CVE-2026-106119 affects @langchain/mongodb through 1.3.0 when untrusted session IDs reach MongoDBChatMessageHistory and multiple users share a collection. Upgrade to 1.3.1 or later.[1], [3]
Imagine a librarian who expects a shelf label but accepts a whole instruction card in its place. The card can tell the filing desk to match more than one shelf, so a request meant for one reader may reach another reader’s history. The fix checks that the ID is a non-empty string and treats it only as a literal value.[1]
Core Concepts & Subsystem Terms
CVE-2026-106119- GitHub-reviewed advisory for query injection in
MongoDBChatMessageHistory; fixed in@langchain/mongodb1.3.1.[1] Session identifier- The value used by
MongoDBChatMessageHistoryto select one conversation history. It must come from trusted, authenticated application context.[1] MongoDB query operator- A structured key that changes how a filter matches documents. A value intended as a literal ID must not be accepted as an arbitrary query structure.[1]
Framework mappings
- CWE reference for the weakness described in this guide: CWE-943
Root Cause Analysis
The GitHub-reviewed advisory assigns CWE-943 and affects @langchain/mongodb versions through 1.3.0. MongoDBChatMessageHistory used sessionId directly as a MongoDB filter value without checking its runtime type. If an application forwards an untrusted request value and stores multiple users’ histories in one collection, a structured value can be interpreted as query logic rather than one session identifier. A caller able to invoke the history operation may then read, modify, or delete another user’s conversation. This is conditional on the application boundary and data-sharing setup; the advisory does not say every LangChain deployment is affected or that the issue is unauthenticated by default.
The merged fix rejects values that are not non-empty strings and wraps the session ID in $eq for getMessages, addMessage, and clear. The advisory identifies 1.3.1 as fixed. Derive the identifier from authenticated server-side context, validate it at runtime, and upgrade; the explicit equality filter is defense in depth, not a substitute for identity authorization.[1], [2], [3]
Step-by-Step Attack Flow
Untrusted input reaches the history boundary
An application is in scope only if it forwards an untrusted session value to the component and stores multiple users’ histories in one collection.[1]
Source Code: Flaw vs. Secure Implementation
These focused excerpts follow the upstream fix and affected query boundary; surrounding imports and class context are omitted, so they are not standalone programs or a proof of concept. TypeScript’s static string annotation does not validate a runtime value. The fix rejects non-string and empty identifiers before use, then wraps the value in MongoDB’s explicit equality operator. The upstream patch applies the $eq form to reads, appends, and deletion, not only this read path.[1], [2]
const document = await this.collection.findOne({
[this.idKey]: this.sessionId,
});
if (typeof sessionId !== "string" || sessionId.length === 0) {
throw new TypeError("sessionId must be a non-empty string");
}
const document = await this.collection.findOne({
[this.idKey]: { $eq: this.sessionId },
});
Engineering & System Hardening Checklist
- ✓Upgrade
@langchain/mongodbto 1.3.1 or later and verify the resolved production dependency.[2], [3] - ✓Never copy a session identifier directly from an untrusted request; derive it from the authenticated principal or a server-controlled session record.[1], [2]
- ✓Validate the identifier’s runtime type and reject empty values before constructing MongoDB filters.[2]
- ✓Keep query predicates fixed in application code and use explicit equality for session identifiers; do not accept caller-supplied filter objects.[2]
- ✓With synthetic accounts and records, test that read, append, and clear operations for one session cannot affect another; confirm the regression test covers each operation.[2]