NoSQL injection is a web security flaw that lets an attacker change the queries an application sends to a NoSQL database such as MongoDB. Instead of guessing a password, the attacker sends a small operator object like {“$ne”: “”}, and the query starts matching records it was never meant to return. That one move can bypass a login, leak documents, or expose an admin account. This guide covers how NoSQL injection works, the common attack types, a real breach it caused, and the exact steps that shut it down. The surprising part is how little code it takes to get in.
Key Takeaways
- NoSQL injection abuses query operators like $ne, $gt, $regex, and $where instead of SQL syntax, so it needs no quotes or UNION statements.
- The most common payload, {“$ne”: “”} or {“$ne”: null}, bypasses authentication by making a filter true for every record.
- OWASP places injection in its A03:2021 category, and its 2021 dataset found some form of injection in 94% of tested applications.
- A real case, Rocket. Chat CVE-2021-22911, chained a blind NoSQL injection into full admin takeover and remote code execution.
- Validating input types on the server is the primary fix, because the attack works by sending an object where a string is expected.
- A web application firewall adds a useful second layer, but it cannot replace application validation, since operators often hide inside JSON bodies.
How Does NoSQL Injection Work?
NoSQL injection works by sending data that the database reads as a command instead of a value. In document databases like MongoDB, queries are objects, so when user input becomes part of that object without a type check, an attacker can inject operators that rewrite the filter.
A normal login query looks for one record where the username and password both match the submitted strings. The code usually trusts that the request fields are strings.
When the app accepts JSON, an attacker can send an object instead. Passing {“$ne”: “”} for the password tells MongoDB “not equal to empty,” which is true for every stored password. The filter now matches the first user in the collection, which is often an administrator.
The same weakness appears in query strings through bracket notation, where ?username[$ne]=&password[$ne]= is parsed into the same operator object on frameworks that auto-convert parameters. NoSQL injection is one branch of a wider injection attack family, and this type-confusion root cause is what lets it slip past classic filters.

According to the OWASP Web Security Testing Guide, filtering common HTML characters will not protect a JSON API, because the special characters that matter are the ones inside JSON.
Once you see that queries are just objects, the next question is what an attacker can actually do with that access.
Common Types of NoSQL Injection
The main types are authentication bypass with comparison operators, blind data extraction with $regex, server-side JavaScript execution with $where, and syntax or operator injection that changes how a query parses.
Each type targets the same trust gap but reaches a different outcome, from a skipped login check to reading data one character at a time.
- Authentication bypass. Operators like $ne, $gt, or $in make a filter true for any record, so the login check passes with {“username”:{“$ne”:null},”password”:{“$ne”:null}}.
- Blind data extraction. The $regex operator tests one character at a time. A different response length or status reveals a match, so an attacker can recover a token or password character by character, the same true/false leakage logic behind the blind SQL injection technique used against relational databases.
- Server-side JavaScript. The $where operator runs JavaScript in the query context. On MongoDB builds before 4.4, where it is not disabled, this can lead to code execution.
- Syntax and operator injection. Extra keys or malformed JSON change how a query parses. In MongoDB, when a document has duplicate keys, only the last value is kept, which attackers use to smuggle operators past checks.

NoSQL injection sits alongside other parser-focused flaws such as the XXE attack, where the payload targets how input is interpreted rather than the database engine itself. That family resemblance is why input handling, not signature blocking, is the durable fix.
Types are easier to grasp once you see how NoSQL injection compares with the SQL injection most developers already know.
NoSQL Injection vs SQL Injection
Both flaws exploit unvalidated input in database queries. Still, SQL injection breaks out of a string using quotes and clauses like UNION. In contrast, NoSQL injection sends operator objects and can execute inside the application layer, not only the database engine.
That difference matters for defense. Tools tuned to spot SQL keywords and quote characters can miss a JSON body that carries a valid-looking operator.
| Aspect | SQL injection | NoSQL injection |
|---|---|---|
| Target database | Relational (MySQL, PostgreSQL) | Document or other NoSQL (MongoDB, CouchDB) |
| Payload style | String with quotes, UNION, comments | JSON operator objects |
| Needs quote characters | Usually yes | No |
| Where it executes | Database engine | Application layer or database layer |
| Typical impact | Full database read and write | Auth bypass, data leak, sometimes JS execution |
| Classic payload | ' OR '1'='1 |
{"$ne": ""} |
“The potential impacts are greater than traditional SQL injection.”
Yes, a single NoSQL payload often extracts less at once than a broad SQL dump. But the ability to run JavaScript through $where can push impact past a typical SQL injection, which is exactly what happened in one widely documented case.
A Real NoSQL Injection Example: Rocket.Chat CVE-2021-22911
In 2021, the security firm Sonar’s disclosure revealed a blind NoSQL injection in Rocket. Chat that needed no login and led to full server takeover. It is tracked as CVE-2021-22911.
The vulnerable getPasswordPolicy method accepted a user-controlled JSON value without validation, and because it did not require authentication, anyone could reach it.
Attackers used the $regex operator to leak a target’s password reset token one character at a time, then reset the password and take over the account. Taking over an admin account led to remote code execution through a webhook. Rocket. Chat patched it in versions 3.11.4, 3.12.4, and 3.13.2 after the HackerOne report.
This was not a rare edge case. OWASP’s 2021 data recorded some form of injection in 94% of tested applications, with 274,000 total occurrences across the category. Injection is also a leading path to data loss, which is why preventing data breaches starts with closing input flaws like this one.
Knowing what a real attack looks like makes the next step practical: checking whether your own application would fall for the same trick.
How to Tell If Your Application Is Vulnerable
An application is likely vulnerable if it passes request data straight into a query without checking that each value is the expected type. You can confirm this by submitting operator objects in place of normal values and watching how the response changes.
Test on a staging copy, never in production, and focus on login, search, and password reset endpoints, which handle untrusted input first.
- Submit {“$ne”: “”} or {“$ne”: null} in a login or search field and watch for a changed or successful response.
- Try bracket notation in the query string, such as field[$ne]=x, on endpoints that parse parameters into objects.
- Probe $regex on a field and compare response length or status codes to spot a match versus no-match signal.
- Check whether $where or server-side JavaScript is reachable and has not been disabled.
- Run an automated scanner such as nosqlmap or nosqli, or work through the PortSwigger Web Security Academy labs, against the staging copy.
Blind extraction can take thousands of requests to recover a single token, so adding rate limiting to login and reset endpoints slows that grind and gives your team time to spot the pattern in the logs.
Hardening the origin matters too, because injection is one of many ways a hacker server foothold begins. Detection shows you where the gaps are, and the fixes below close them for good.
How to Prevent NoSQL Injection
Prevent NoSQL injection by validating that every input is the expected type before it reaches a query, then layering sanitization, least privilege, and edge filtering on top. The root cause is type confusion, so type checking does the heavy lifting.
Treat the steps below as layers. Each one on its own leaves a gap, but together they remove the common paths an attacker relies on.
- Validate input types. Reject an object where a string belongs. This alone stops the classic $ne bypass.
- Use schema validation. Enforce the expected shape with a library like Zod or Joi, or with your ODM schema, so unexpected keys are dropped.
- Sanitize operators. Strip keys that start with $ using a library such as mongo-sanitize before building the query.
- Apply least privilege and disable $where. Limit database roles and turn off server-side JavaScript so a missed check cannot become code execution.
- Add edge defenses. An advanced web application firewall can block known operator patterns, although it cannot see every operator hidden in a JSON body.
At the edge, a custom WAF ruleset can flag the $ne and $regex patterns that show up in operator injection, and managed rule packs like the OWASP Core Rule Set already include signatures for common injection payloads.
Because operator injection often rides in JSON, keep inspection close to users with edge security solutions, and pair the application-layer WAF with a network firewall solution so both the traffic and the infrastructure layer are covered.
Final Thought On NoSQL Injection
NoSQL injection is dangerous precisely because it is simple. An attacker does not need special characters or deep database knowledge, only an object sent where the code expected a string. That single type mismatch can turn a login form into an open door.
The fix follows the same logic. Validate input types first, enforce a schema, strip operators, and restrict what the database can do. Edge filtering and a WAF then catch what slips through. Strong applications treat every request value as untrusted until proven to be the right type, and they layer defenses so no single mistake is fatal.
Common Questions About NoSQL Injection
Can a WAF stop NoSQL injection on its own?
A WAF blocks known operator patterns and adds a valuable layer, but it can miss operators buried inside JSON request bodies. Application-level type validation remains the primary defense, with the WAF as backup.
What is the most common NoSQL injection payload?
The classic payload is {“$ne”: “”} or {“$ne”: null} in a password field, which makes the filter match every record and bypasses the login check.
How is NoSQL injection different from SQL injection?
SQL injection breaks out of a string with quotes and clauses like UNION and runs in the database engine. NoSQL injection sends operator objects, needs no quotes, and can execute in the application layer as well as the database.