Summary
We scanned mongo-mcp using agent-audit and found that the find and deleteOne tools pass unvalidated MongoDB query operators directly to the driver, enabling operator injection attacks.
OWASP Agentic AI Top 10: A03 - Insufficient Input/Output Validation
Finding: MongoDB Operator Injection via Unfiltered Query Filters
Files:
src/tools/documents/find.ts — line 47
src/tools/documents/delete-one.ts — line 32
Both tools accept a filter object from the MCP tool call and pass it directly to the MongoDB driver with no operator filtering:
// src/tools/documents/find.ts:42-50
async execute(params: FindParams) {
const collection = this.validateCollection(params.collection);
const results = await db
.collection(collection)
.find(params.filter || {}) // ← filter passed directly, no operator validation
.project(params.projection || {})
.limit(Math.min(params.limit || 10, 1000))
.toArray();
// src/tools/documents/delete-one.ts:28-32
async execute(params: DeleteOneParams) {
const collection = this.validateCollection(params.collection);
const filter = this.validateObject(params.filter, "Filter");
const result = await db.collection(collection).deleteOne(filter); // ← direct pass
validateObject (in base/tool.ts) only checks that the value is an object — it does not filter MongoDB operators.
Attack Vectors
1. ReDoS via $regex operator (any MongoDB version)
An AI agent receiving a malicious prompt could call find with:
{ "filter": { "name": { "$regex": "^(a+)+$", "$options": "i" } } }
The catastrophic backtracking regex would block the MongoDB thread pool, causing server-side denial of service.
2. JavaScript execution via $where (MongoDB instances with javascriptEnabled: true)
On MongoDB deployments that have not explicitly disabled JavaScript execution:
{ "filter": { "$where": "function() { sleep(5000); return true; }" } }
$where is disabled by default in MongoDB 4.4+, but many deployments still use older versions or have security.javascriptEnabled: true set explicitly.
3. Authentication bypass pattern via $ne/$gt
{ "filter": { "role": { "$ne": "user" } } }
Can be used to enumerate privileged documents by querying "everything that is NOT user".
4. Recursive operator nesting for query amplification
Deeply nested operators like $or, $and, $not can be nested to force O(n^k) query plans, causing resource exhaustion.
Why This Matters for MCP
MCP tools receive inputs from AI agents. A document the AI reads, a webpage it visits, or a user message can contain a prompt injection payload that causes the AI to call find or deleteOne with a crafted MongoDB operator. Since the filter is passed directly to the driver, any valid MongoDB operator the AI sends will execute.
Suggested Fix
Implement a recursive operator allowlist or blocklist before executing the query:
const BLOCKED_OPERATORS = new Set(['$where', '$function', '$accumulator']);
function sanitizeFilter(filter: Record<string, unknown>): Record<string, unknown> {
for (const key of Object.keys(filter)) {
if (BLOCKED_OPERATORS.has(key)) {
throw new McpError(ErrorCode.InvalidRequest, `Operator ${key} is not permitted`);
}
const value = filter[key];
if (value && typeof value === 'object' && !Array.isArray(value)) {
sanitizeFilter(value as Record<string, unknown>);
}
}
return filter;
}
For $regex specifically, validate that the pattern is not catastrophically backtracking using a safe-regex library before executing the query.
Found using agent-audit — static analysis for MCP servers. OWASP Agentic AI Top 10 reference: A03:2025 Insufficient Input/Output Validation.
Summary
We scanned
mongo-mcpusing agent-audit and found that thefindanddeleteOnetools pass unvalidated MongoDB query operators directly to the driver, enabling operator injection attacks.OWASP Agentic AI Top 10: A03 - Insufficient Input/Output Validation
Finding: MongoDB Operator Injection via Unfiltered Query Filters
Files:
src/tools/documents/find.ts— line 47src/tools/documents/delete-one.ts— line 32Both tools accept a
filterobject from the MCP tool call and pass it directly to the MongoDB driver with no operator filtering:validateObject(inbase/tool.ts) only checks that the value is an object — it does not filter MongoDB operators.Attack Vectors
1. ReDoS via
$regexoperator (any MongoDB version)An AI agent receiving a malicious prompt could call
findwith:{ "filter": { "name": { "$regex": "^(a+)+$", "$options": "i" } } }The catastrophic backtracking regex would block the MongoDB thread pool, causing server-side denial of service.
2. JavaScript execution via
$where(MongoDB instances withjavascriptEnabled: true)On MongoDB deployments that have not explicitly disabled JavaScript execution:
{ "filter": { "$where": "function() { sleep(5000); return true; }" } }$whereis disabled by default in MongoDB 4.4+, but many deployments still use older versions or havesecurity.javascriptEnabled: trueset explicitly.3. Authentication bypass pattern via
$ne/$gt{ "filter": { "role": { "$ne": "user" } } }Can be used to enumerate privileged documents by querying "everything that is NOT user".
4. Recursive operator nesting for query amplification
Deeply nested operators like
$or,$and,$notcan be nested to force O(n^k) query plans, causing resource exhaustion.Why This Matters for MCP
MCP tools receive inputs from AI agents. A document the AI reads, a webpage it visits, or a user message can contain a prompt injection payload that causes the AI to call
findordeleteOnewith a crafted MongoDB operator. Since the filter is passed directly to the driver, any valid MongoDB operator the AI sends will execute.Suggested Fix
Implement a recursive operator allowlist or blocklist before executing the query:
For
$regexspecifically, validate that the pattern is not catastrophically backtracking using a safe-regex library before executing the query.Found using agent-audit — static analysis for MCP servers. OWASP Agentic AI Top 10 reference: A03:2025 Insufficient Input/Output Validation.