Logging Monitoring Failures in Fastapi with Mongodb
Logging Monitoring Failures in Fastapi with Mongodb — how this specific combination creates or exposes the vulnerability
When FastAPI applications interact with MongoDB without structured logging and runtime monitoring, security-relevant events are often underrecorded or recorded in a way that impedes detection. This combination can hide attacks such as injection attempts, unauthorized data access, and privilege escalation, which are relevant to checks such as Input Validation, Data Exposure, and Property Authorization in a middleBrick scan.
Common gaps include missing log context (e.g., user ID, request ID), unparameterized MongoDB queries that make it hard to distinguish legitimate from malicious patterns, and lack of audit trails for sensitive operations. For example, a route that performs db.users.find_one({"username": username}) without sanitizing or logging the input may allow an attacker to probe for injection or enumeration behavior, and the absence of logs means the activity goes undetected. Similarly, inconsistent error handling can leak stack traces or database details, contributing to Data Exposure findings by exposing internal schema or server information in responses.
Another specific risk arises when FastAPI endpoints construct MongoDB filters dynamically from user-supplied JSON without validation. An attacker may submit nested objects or special operators (e.g., {$ne:, $where:) that alter query intent, and without proper logging these manipulations are difficult to trace. middleBrick tests such scenarios under Input Validation and Property Authorization, noting when filters allow unintended document access or bypass intended authorization logic. Inadequate logging also weakens accountability for administrative actions, such as changes to roles or sensitive documents, which should be recorded with sufficient metadata to support audits and incident response.
Operational practices affect detection as well. If logs are not centralized or rotated carefully, critical events may be lost due to truncation or retention policies. A middleBrick scan can surface Data Exposure and Encryption findings when logs inadvertently contain or omit information that affects confidentiality. For example, logging full MongoDB query results that include tokens or personal data increases exposure risk, while missing logs of authentication failures reduces visibility into brute-force attempts. Instrumentation that captures request identifiers, endpoint paths, method, outcome status, and sanitized filter summaries helps correlate findings across the 12 parallel checks and provides the context needed for effective remediation.
Mongodb-Specific Remediation in Fastapi — concrete code fixes
Implement structured logging and validated MongoDB interactions in FastAPI to reduce the attack surface and improve auditability. Use a logging framework that supports structured output (e.g., JSON) and include consistent fields such as request ID, endpoint, method, authenticated subject (if any), and a sanitized representation of database operations.
import logging
import uuid
from fastapi import FastAPI, Request, HTTPException
from pymongo import MongoClient
from bson import json_util
import json
logger = logging.getLogger("api")
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
formatter = logging.Formatter('{"time": "%(asctime)s", "level": "%(levelname)s", "request_id": "%(request_id)s", "message": %(message)s}')
handler.setFormatter(formatter)
logger.addHandler(handler)
app = FastAPI()
client = MongoClient("mongodb://localhost:27017")
db = client["appdb"]
users = db["users"]
@app.middleware("http")
async def add_request_id(request: Request, call_next):
request.state.request_id = str(uuid.uuid4())
response = await call_next(request)
return response
def sanitize_filter(filter_doc):
# Allow only simple equality filters for this example
allowed_keys = {"username", "email", "role"}
sanitized = {}
for k, v in filter_doc.items():
if k in allowed_keys and isinstance(v, str):
sanitized[k] = v
return sanitized
@app.get("/users/{username}")
async def get_user(username: str, request: Request):
safe_username = sanitize_filter({"username": username})
request_id = request.state.request_id
try:
result = users.find_one(safe_username)
if result is None:
logger.info(json.dumps({"event": "user_not_found", "filter": safe_username, "request_id": request_id}))
raise HTTPException(status_code=404, detail="User not found")
logger.info(json.dumps({"event": "user_found", "filter": safe_username, "request_id": request_id}))
# Remove sensitive fields before sending
result.pop("password_hash", None)
result.pop("api_key", None)
return dict(result)
except Exception as e:
logger.warning(json.dumps({"event": "db_error", "error": str(e), "request_id": request_id}))
raise HTTPException(status_code=500, detail="Internal server error")
The example demonstrates input sanitization to limit allowed filter keys and types, reducing the risk of injection and unintended enumeration. Logging includes a request ID and a concise event payload that avoids exposing sensitive data while still enabling traceability. For broader coverage, validate and type incoming filter objects more rigorously, and consider using MongoDB’s collation and field-level encryption features to reduce exposure of sensitive fields.
For operations that modify data, log before-and-after states at an appropriate level of abstraction, excluding secrets. Enforce authentication and role-based checks in application code and log authorization decisions to support investigations. These practices align with expectations from middleBrick’s checks such as Authentication, BOLA/IDOR, and Data Exposure, and provide the audit trail necessary to demonstrate compliance with frameworks like OWASP API Top 10 and SOC2.