NoSQL injection occurs when an application builds a NoSQL query, for example a MongoDB query, from user input without keeping that input strictly as data. Because many NoSQL drivers accept query objects, an attacker who can inject operators such as $ne, $gt, or $regex can alter the query's logic to bypass authentication or extract data, and where server-side JavaScript like $where is enabled, reach code execution. It is closely related to SQL injection but exploits the document and operator model rather than SQL syntax.
What NoSQL injection is
NoSQL databases like MongoDB query with structured objects rather than a text language. An application might look up a user with { username: input_user, password: input_pass }. The problem appears when the framework lets a client submit not just a string but a structured value.
If an attacker can make input_pass become an object like { "$ne": null } instead of a plain string, the query condition changes from equals a password to not equal to null, which is true for every record. The input has crossed from data into query logic. This commonly happens when request bodies are parsed into nested objects and passed straight into the query.
The abuse and payload
Shown for defensive context:
- Authentication bypass: send a JSON body
{"username": {"$ne": null}, "password": {"$ne": null}}so the query matches any user, or target a known user with{"username": "admin", "password": {"$ne": ""}}. - Operator injection for extraction:
$regexlets an attacker infer values character by character, for example{"password": {"$regex": "^a"}}to learn the first character from the response. - Server-side JavaScript: where
$whereormapReduceruns JavaScript, an injected expression can execute logic on the database, in some setups reaching code execution. - Operator injection in query strings: frameworks that parse
user[$ne]=1into an object reintroduce the flaw even without a JSON body.
These logic-level bypasses are a standard check against authentication and search endpoints during web application penetration testing.
How to defend
Keep user input as data and never as query structure:
- Cast and validate types: ensure fields that should be strings are strings before they reach the query, rejecting objects and arrays where a scalar is expected.
- Use the driver's safe query construction and parameterization rather than merging raw request objects into a query.
- Disable server-side JavaScript such as
$whereandmapReduceon untrusted input, and turn it off at the database level if unused. - Validate against a schema so unexpected operators and nested structures are rejected at the boundary.
The core discipline mirrors SQL injection defense: separate data from the query, and never trust the shape of client input.
References
- [1]OWASP: Testing for NoSQL Injection(OWASP)
- [2]PortSwigger: NoSQL injection(PortSwigger)
- [3]MITRE ATT&CK: Exploit Public-Facing Application (T1190)(MITRE)