Fix NoSQL Injection in FastAPI
NoSQL Injection in FastAPI targets the lack of schema enforcement when passing user-controlled dictionaries directly into database drivers like Motor or PyMongo. By injecting MongoDB operators such as $gt, $ne, or $regex, attackers can bypass authentication or exfiltrate the entire collection. If you're pulling raw JSON from 'request.json()' and dumping it into a 'find_one()' call, you're pwned.
The Vulnerable Pattern
from fastapi import FastAPI, Request from motor.motor_asyncio import AsyncIOMotorClientapp = FastAPI() client = AsyncIOMotorClient(‘mongodb://localhost:27017’) db = client.auth_db
@app.post(‘/login’) async def login(request: Request): # VULNERABLE: Direct dictionary injection # Attacker sends: {“username”: “admin”, “password”: {“$ne”: “wrong”}} data = await request.json() user = await db.users.find_one({“username”: data[‘username’], “password”: data[‘password’]}) if user: return {‘status’: ‘authenticated’} return {‘status’: ‘denied’}
The Secure Implementation
The fix relies on Strict Typing via Pydantic. In the vulnerable snippet, 'request.json()' allows the 'password' field to be an object, which MongoDB interprets as a query operator. By defining a Pydantic model where fields are explicitly typed as 'str', FastAPI's validation layer rejects any non-string input before it ever touches the database driver. This effectively neutralizes operator injection by ensuring query parameters are treated as literal values, not instructions.
from fastapi import FastAPI from pydantic import BaseModel, Field from motor.motor_asyncio import AsyncIOMotorClientapp = FastAPI() client = AsyncIOMotorClient(‘mongodb://localhost:27017’) db = client.auth_db
class UserCredentials(BaseModel): username: str = Field(…, min_length=1) password: str = Field(…, min_length=1)
@app.post(‘/login’) async def login(creds: UserCredentials): # SECURE: Pydantic enforces types. # If ‘password’ is a dict/operator, FastAPI returns a 422 Unprocessable Entity. user = await db.users.find_one({ “username”: creds.username, “password”: creds.password }) if user: return {‘status’: ‘authenticated’} return {‘status’: ‘denied’}
Your FastAPI API
might be exposed to NoSQL Injection
74% of FastAPI apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.