Skip to content

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.

Authentication bypass, data extraction (boolean/time-based), and in some cases server-side JavaScript execution ($where, mapReduce).

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.

# 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 delay

Confirm by response difference (login OK/KO) or by timing when blind.

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 rebuilt

Automate 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.

NoSQLMap, nosqli, and Burp to inject operators into JSON/parameters.

ATO (login bypass), data dump, and JS-interpreter RCE in configs with $where/ mapReduce enabled.

  • 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).

DB and app logs, WAF with JSON inspection.

  1. Validate and cast types: expect a string where a string belongs; reject user objects/operators.
  2. Don’t pass user objects straight into the query; build it with concrete fields.
  3. Disable server-side $where/JS if unused.
  4. ODM/schemas (Mongoose) with strict validation.

Rotate credentials if there was a dump, fix type handling, and add operator detection.

  • 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).

  • 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.