Ssrf Server Side in Fastapi with Mongodb
Ssrf Server Side in Fastapi with Mongodb — how this specific combination creates or exposes the vulnerability
Server Side Request Forgery (SSRF) in a FastAPI application that uses MongoDB can arise when the server accepts a URL from an attacker and uses it to make an HTTP request, often to fetch or transform data before storing or retrieving documents in MongoDB. If the application does not validate or restrict the destination, an attacker can direct requests to internal services that are not exposed publicly, such as the MongoDB instance’s own connection endpoint, metadata services, or internal APIs. Because FastAPI applications commonly parse user input for query parameters or request bodies, an SSRF vector can be introduced through endpoints that accept a URL or host/port configuration for downstream requests.
When SSRF is combined with MongoDB, there are two notable risk dimensions. First, SSRF can be used to probe internal infrastructure; for example, an attacker might supply a URL pointing to the FastAPI server’s own MongoDB connection string or an administrative endpoint that reveals configuration details. Second, if the application embeds user-controlled data into MongoDB without strict validation, SSRF can facilitate injection of malicious payloads that are later read by internal services or used in log injection or in stored data that triggers further issues when processed. Because FastAPI routes often deserialize JSON directly into Pydantic models, insufficient validation of URLs or host inputs can allow an SSRF attack to reach internal MongoDB-related endpoints or any backend service the server is permitted to contact.
OpenAPI/Swagger spec analysis can highlight parameters that accept URLs or host strings without adequate constraints, and runtime testing can confirm whether the unauthenticated attack surface allows SSRF against MongoDB-related internal endpoints. The 12 security checks run in parallel by middleBrick include Input Validation and Data Exposure, which help identify whether user-supplied URLs can reach internal services and whether sensitive data might be leaked through SSRF-affected endpoints.
Mongodb-Specific Remediation in Fastapi — concrete code fixes
To mitigate SSRF when working with MongoDB in FastAPI, validate and constrain all user-supplied inputs that influence network requests or data storage. Use strict allowlists for protocols and hosts, avoid forwarding user URLs directly, and ensure MongoDB connection strings are sourced from server-side configuration rather than client input. The following code examples illustrate secure patterns.
1. Validate URLs against an allowlist
Reject URLs with non-HTTP schemes and unexpected hosts. Do not rely on simple prefix checks; parse the URL and enforce allowed domains and ports.
from urllib.parse import urlparse
from fastapi import FastAPI, HTTPException
app = FastAPI()
ALLOWED_HOSTS = {"api.example.com", "internal.example.com"}
def validate_url(user_url: str) -> str:
parsed = urlparse(user_url)
if parsed.scheme not in {"http", "https"}:
raise HTTPException(status_code=400, detail="Only HTTP and HTTPS are allowed")
if parsed.hostname not in ALLOWED_HOSTS:
raise HTTPException(status_code=400, detail="Host not allowed")
return user_url
@app.post("/fetch-external/")
async def fetch_external(url: str):
target = validate_url(url)
# Perform the request with a strict timeout and no redirects to internal hosts
# ... your HTTP client logic here ...
return {"status": "ok"}
2. Use server-side MongoDB connection, never forward user input to the database layer
Keep MongoDB connection strings in environment variables or a secure configuration store. Use a MongoDB client that enforces TLS and bind to a least-privilege network. Never construct connection URIs from user input.
from fastapi import FastAPI, HTTPException
from pymongo import MongoClient
import os
app = FastAPI()
MONGO_URI = os.getenv("MONGO_URI")
if not MONGO_URI:
raise RuntimeError("MONGO_URI environment variable is required")
client = MongoClient(MONGO_URI, tls=True, serverSelectionTimeoutMS=5000)
db = client.get_database("secure_db")
@app.get("/items/{item_id}")
async def get_item(item_id: str):
# Validate item_id to prevent NoSQL injection
if not item_id.isalnum():
raise HTTPException(status_code=400, detail="Invalid item ID")
item = db.items.find_one({"_id": item_id})
if item is None:
raise HTTPException(status_code=404, detail="Item not found")
# Explicitly exclude sensitive fields before returning
item.pop("password_hash", None)
item.pop("api_key", None)
return {"id": item["_id"], "name": item["name"]}
3. Harden request processing and logging
Do not reflect user-provided URLs in responses or logs in a way that could be used for SSRF-based data exfiltration. Sanitize inputs before storing them, and apply schema validation to MongoDB documents to avoid injection of unexpected fields.
from fastapi import FastAPI
from pydantic import BaseModel, constr
app = FastAPI()
class ItemCreate(BaseModel):
name: constr(min_length=1, max_length=100)
# Avoid storing raw user URLs; if required, validate and normalize
redirect_url: constr(regex=r'^https?://(example\.com|api\.example\.com)/.*$') = ""
@app.post("/items/")
async def create_item(payload: ItemCreate):
# Store sanitized data; do not store raw redirect_url without validation
document = {
"name": payload.name,
"redirect_url": payload.redirect_url
}
result = db.items.insert_one(document)
return {"id": str(result.inserted_id)}
These measures reduce the attack surface for SSRF against MongoDB in FastAPI by ensuring that user input cannot reach internal services or be stored in a form that leads to further compromise.