Join our Newsletter — 33% off our NHI Course
Home› Guides› NoSQL Injection Prevention Guide: MongoDB, Operators and Query…
Guide Web & API Security

NoSQL Injection Prevention Guide: MongoDB, Operators and Query Builders

PDF for newsletter subscribers · free to read online

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 27 October 2026 10 min read
On this page

Switching from SQL to a document database does not remove injection; it changes its shape, from breaking out of a string to smuggling a query operator in where the code expected a value. In MongoDB and similar stores, queries are objects, and web frameworks happily turn request parameters and JSON bodies into nested objects. If an application drops those objects straight into a filter, an attacker can change what the query means, and if server-side JavaScript is enabled, can sometimes make the database run code. This guide explains how NoSQL injection works, where it appears in Node.js, Python and Java stacks, how to detect it, and the specific driver, ODM and server settings that prevent it. It is for developers and application security engineers working with MongoDB and other document databases. Database hardening beyond injection is covered in the MongoDB Security Guide.

Key takeaways

  • Query objects are not parameterisation. The OWASP NoSQL Security Cheat Sheet warns that building a filter object does not prevent operator injection when the untrusted value is itself an object.
  • Type checks are the core defence. Confirm every value is the scalar type you expect (string, number, ObjectId) before it reaches a filter.
  • Turn on the ODM's protections. Mongoose sanitizeFilter wraps untrusted objects in $eq and rejects $where, $expr, $jsonSchema and $text; strictQuery controls non-schema fields.
  • Disable server-side JavaScript if you do not use it. security.javascriptEnabled: false or --noscripting removes the $where, $function, $accumulator and map-reduce execution paths.
  • Least privilege limits the blast radius. An application user that can only read and write its own collections cannot be used to drop databases or read other tenants' data.

How the attack works

NoSQL injection, catalogued as CAPEC-676, has three main forms. All of them start with untrusted input changing the structure of a query rather than just supplying a value.

FormWhat goes wrongTypical result
Operator (query selector) injectionA field expected to be a string arrives as an object containing a MongoDB operator such as $ne, $gt, $in or $regex, so an equality check becomes a comparisonAuthentication bypass, records returned for other users, enumeration of values one character at a time
JavaScript injectionUntrusted input is concatenated into a $where expression, a $function body or a map-reduce function that the server executesArbitrary logic in the query, data extraction, CPU exhaustion
Query string or syntax injectionThe application builds a query as text and parses or evaluates it (the OWASP cheat sheet's "NEVER do this" example uses eval)Full control of the query, potentially code execution in the application

Operator injection is the most common because it needs no unusual code. The OWASP Node.js Security Cheat Sheet shows how Express's extended query string parsing turns ?foo=bar into a string, but bracket syntax such as ?foo[bar]=baz into an object { bar: 'baz' }. A JSON body can carry any nested object directly. If the handler writes { username: req.body.username, password: req.body.password }, whoever controls the body decides whether each field is a value or an operator. The OWASP cheat sheet gives the canonical illustration: MongoDB interprets { name: { $ne: "" } } as "name is not empty", which matches almost every document.

$regex deserves separate mention: even where operators are expected, a client-supplied regular expression can be used both to infer data (by testing prefixes) and to cause denial of service with a pattern that backtracks badly. See the Regular Expression Denial of Service Guide.

Where it shows up

  • Login and token lookups: queries that match a username and a password hash, a reset token or an API key are the highest-impact targets, because a comparison operator turns "equals this secret" into "matches anything".
  • Search and filter APIs: endpoints that accept a filter object from the client "for flexibility", especially admin and reporting APIs and generic REST layers over MongoDB.
  • Object lookups by ID: a route that expects an ObjectId but passes whatever arrives into findOne.
  • Update operations: a client-controlled update document can include operators such as $set on fields the user should not change, which is the mass assignment problem in document form (ASVS V15.3.3).
  • Aggregation pipelines: stages assembled from user input, including $lookup to other collections, and $function or $accumulator bodies.
  • Other stores: the same pattern applies wherever queries are structured data built from input, including CouchDB selectors, Elasticsearch query DSL and DynamoDB expressions. Cassandra CQL behaves more like SQL and needs prepared statements.

Impact

ImpactHow it arisesWhat limits it
Authentication bypassOperator in a credential or token fieldType checks, comparing secrets in application code after fetching by username
Data disclosureBroadened filters, cross-tenant matches, prefix inference with $regexServer-side tenant filter added after user input, least privilege, field projection
Data tamperingClient-controlled update operatorsAllowlisted update fields, ODM strict mode
Denial of serviceUnindexed operator queries, $where collection scans, regex backtrackingDisabling server-side JavaScript, query timeouts (maxTimeMS), rejecting $regex from clients
Code execution in the applicationQuery text passed to eval or similarNever evaluate input as code

MongoDB's own documentation notes that $where evaluates JavaScript for each document, cannot use indexes and alone requires a collection scan, so injected $where clauses are a performance risk even before any data leaks.

Detection

  • Code review and SAST: flag any place where request data (req.body, req.query, req.params, framework equivalents) flows into find, findOne, updateOne, aggregate or deleteMany without a type check; flag every use of $where, $function, $accumulator, mapReduce and eval.
  • Testing: in authorised tests, submit bracket-notation and JSON object values for fields that should be strings and confirm the application rejects them with a 400 rather than changing results.
  • Request monitoring: log and alert on request parameters or JSON keys that start with $ on endpoints that never legitimately receive them; a WAF rule can do this at the edge, but treat it as a signal, not the fix.
  • Database monitoring: the OWASP cheat sheet recommends alerting on spikes in queries, slow queries, large exports and suspicious commands such as $where and map-reduce jobs. MongoDB's profiler and slow query log show unexpected operators and collection scans.
  • Configuration checks: confirm in every environment whether server-side JavaScript is enabled and whether the application user has more than readWrite on its own database.

Prevention and hardening

1. Validate types and fields at the boundary

The OWASP NoSQL cheat sheet's safe pattern is simple: check that the value is a string (or the expected type) before building the filter, and reject the request otherwise. Do this with a schema validator on every route (JSON Schema, Zod, Joi, Pydantic, Bean Validation) so types, allowed fields and lengths are declared once. ASVS 5.0 V1.2.4 requires database queries, NoSQL included, to use parameterised queries, ORMs or other protection against injection, and V2.2.2 requires validation at a trusted service layer.

  • Prefer allowlists to denylists: OWASP notes that rejecting any serialised body containing "$ is a denylist that also blocks legitimate strings starting with $ and does not validate types. Use it, if at all, as an extra layer.
  • Cast IDs: convert ID parameters to ObjectId (or the expected type) and reject on failure.
  • Limit query string parsing: check your framework's query parser setting; if bracket-to-object parsing is not needed, configure the simple parser.

2. Use driver builders and ODM protections

StackSafe patternSetting or API
Node.js, MongooseWrap untrusted objects in $eq; block JavaScript and expression operatorssanitizeFilter: true (Mongoose 6 and later, global or per query); mongoose.trusted() only for server-built selectors
Node.js, MongooseControl fields not in the schemastrictQuery: 'throw' raises an error; true silently removes the field, which can turn a filter into {} and match every document
Node.js, native driverType check every value; build filters only from validated scalarsMiddleware such as express-mongo-sanitize (named in the OWASP Node.js cheat sheet) as an extra layer
Python, PyMongoisinstance(value, str) before find_oneOWASP NoSQL cheat sheet example
Java driverTyped builders such as Filters.eq("field", value) with a String valueOWASP NoSQL cheat sheet example

The strictQuery: true behaviour is a trap worth calling out: Mongoose's documentation explains that stripping an unknown field from a filter can leave an empty filter that returns all documents. For security-sensitive queries, 'throw' is safer.

3. Never let clients send operators or code

  • Server-built queries only: the OWASP cheat sheet says not to accept raw JSON query fragments from the client, and to disallow client-controlled $where, $regex and $expr unless strictly required and validated. Expose named filters (status, date range, owner) and build the operator on the server.
  • Search: use a text index with $text on controlled input rather than client regexes; if regex search is required, escape the input (ASVS V1.2.9) and bound its length.
  • Updates: build update documents from an allowlist of fields; never pass req.body as the update.

4. Harden the server

  • Disable server-side JavaScript with security.javascriptEnabled: false or --noscripting on mongod and mongos if the application does not use $where, $function, $accumulator or map-reduce. MongoDB notes scripting is enabled by default and map-reduce has been deprecated since MongoDB 5.0.
  • Least privilege: give the application a dedicated user with access only to its own database or collections, and separate users for admin, backup and read-only work, as the OWASP cheat sheet recommends.
  • Tenant isolation: add the tenant or owner condition on the server after user input is merged, so no client field can override it.
  • Timeouts: set maxTimeMS on queries that run on user-influenced filters.

Framework mapping

FrameworkReference
MITRE CAPECCAPEC-676 NoSQL Injection
MITRE ATT&CKT1190 Exploit Public-Facing Application
OWASP ASVS 5.0V1.2.4 (database injection), V1.2.9 (regex escaping), V2.2.2 (server-side validation), V15.3.3 (mass assignment)
NIST SP 800-53 Rev. 5SI-10 Information Input Validation; AC-6 Least Privilege; SA-11 Developer Testing and Evaluation
NIST CSF 2.0PR.PS-06 Secure software development practices

Where identity fits

The database credential the application uses is a non-human identity, and its permissions decide how bad an injection can get. Keep it in a secrets manager, scope it to the application's own database, rotate it, and never reuse an admin account for the application. See the MongoDB Atlas Credentials Security Guide.

Practitioner checklist

  • Add schema validation to every route that feeds a database query, rejecting objects where scalars are expected.
  • Enable Mongoose sanitizeFilter globally and use mongoose.trusted() only for server-built selectors.
  • Set strictQuery: 'throw' on schemas used for authentication, authorisation and tenant lookups.
  • Remove any code path that evaluates query text or passes client JSON as a filter, update or pipeline.
  • Replace client-supplied $regex with $text or escaped, length-bounded patterns.
  • Disable server-side JavaScript on mongod and mongos unless a reviewed feature needs it.
  • Scope the application database user to its own database and store its credential in a secrets manager.
  • Add SAST rules and authorised test cases for operator injection, and alert on $-prefixed keys in requests.

Standards and references

Related NHI Mgmt Group resources: MongoDB Security Guide · SQL Injection Prevention Guide · Input Validation and Output Encoding Guide · Regular Expression Denial of Service Guide

PDF for subscribers

Take this guide with you

Every section, table and checklist in one PDF, with links to the sources and related guides. Subscribe to our weekly NHI & AI Identity Journal and we’ll email you a download link.

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 27 October 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org

PDF Downloads for Newsletter Subscribers

Get the guide

Enter your details and we’ll email you a download link.

The full guide is free to read online. The PDF is a thank you for subscribing.

Fill in all fields marked * and tick the PDF box to continue.