GuardAPI Logo
GuardAPI

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 AsyncIOMotorClient

app = 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 AsyncIOMotorClient

app = 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’}

System Alert • ID: 9290
Target: FastAPI API
Potential Vulnerability

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.

RUN FREE SECURITY DIAGNOSTIC
GuardLabs Engine: ONLINE

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.