NoSQL Injection
NoSQL injection manipulates MongoDB, Firebase, and other NoSQL database queries by injecting operator objects, bypassing authentication and exposing all records.
What Is NoSQL Injection?
NoSQL injection targets applications using non-relational databases like MongoDB, CouchDB, or Firebase Firestore. Instead of SQL syntax, attackers inject JavaScript operators or query objects to manipulate the database query logic, bypassing authentication or exfiltrating data.
How It Works
A MongoDB login endpoint:
// Vulnerable — user-controlled JSON merged directly into query
app.post("/login", async (req, res) => {
const { username, password } = req.body
const user = await db.collection("users").findOne({
username: username,
password: password, // Attacker can make this a query operator
})
if (user) return res.json({ token: generateToken(user) })
res.status(401).json({ error: "Invalid credentials" })
})The attacker sends:
{
"username": "admin",
"password": { "$ne": null }
}The query becomes:
db.users.findOne({ username: "admin", password: { $ne: null } })$ne: null means "password is not null" — which is true for every user. The attacker logs in as admin without knowing the password.
Exfiltration with $regex:
{ "password": { "$regex": "^a" } }By iterating through regex patterns, attackers can extract passwords character by character.
Real-World Impact
- Authentication bypass — log in as any user without credentials
- Data enumeration — extract all documents using
$regexor$where - Full collection dump — operators like
$gt: ""match all documents - JavaScript injection —
$whereoperator executes arbitrary JS in MongoDB
How to Fix
Validate and sanitize input — reject operator objects:
def sanitize_mongo_input(value):
if isinstance(value, dict):
raise ValueError("Object input not allowed")
if isinstance(value, str) and value.startswith("$"):
raise ValueError("Operator input not allowed")
return value
username = sanitize_mongo_input(request.json.get("username"))
password = sanitize_mongo_input(request.json.get("password"))Use a schema validation library (Pydantic, Joi, Zod):
from pydantic import BaseModel
class LoginRequest(BaseModel):
username: str # Pydantic enforces string type — rejects objects
password: str
@app.post("/login")
async def login(body: LoginRequest):
user = await db.users.find_one({"username": body.username, "password": body.password})Avoid $where entirely — it evaluates JavaScript and is inherently dangerous.
Use bcrypt for passwords — store hashes, not plaintext, so regex extraction is useless.
What VibeWShield Detects
VibeWShield injects MongoDB operator payloads ($ne, $gt, $regex, $where) into JSON request bodies and URL parameters. It looks for authentication bypass (unexpected 200 responses) and data exposure patterns in responses.
Free security scan
Test your app for NoSQL Injection
VibeWShield automatically checks for NoSQL Injection and 40+ other vulnerabilities using 63 scanners — in under 3 minutes, no signup required.
Scan your app free