Api Key Exposure in Fastapi with Firestore
Api Key Exposure in Fastapi with Firestore — how this specific combination creates or exposes the vulnerability
When a FastAPI service uses Google Cloud Firestore and inadvertently exposes an API key or service account credential, the impact is compounded by Firestore’s broad, default permissions and the typical volume of sensitive data stored in NoSQL document stores. In a typical misconfiguration, developers embed an API key or a credential directly in source code, environment variables, or configuration files that the FastAPI process reads at runtime. If the application logs requests, returns stack traces, or exposes debug endpoints, these secrets can leak through application output or error responses.
Firestore rules that are permissive or improperly scoped can allow an authenticated caller (or an attacker who has obtained a leaked key) to read or write collections that should be restricted. For example, a key intended for server-side access might be used client-side, bypassing intended trust boundaries. FastAPI routes that construct Firestore queries using unchecked user input can inadvertently expose document paths or metadata, and if a key is present in query parameters, headers, or request bodies, middleBrick’s Data Exposure and Input Validation checks will flag the risk of key exfiltration through logs or error messages.
An attack flow might involve an attacker probing unauthenticated endpoints to locate API key references in OpenAPI/Swagger specs or in verbose error responses. If a route accepts parameters that map to Firestore document IDs or collection names without proper validation, this can merge with key exposure to enable BOLA/IDOR or BFLA patterns. middleBrick’s LLM/AI Security checks are particularly effective here because they detect system prompt leakage and test for jailbreaks or data exfiltration attempts that could exploit verbose error handling or misconfigured assistant endpoints that may surface key material.
During a scan, middleBrick tests unauthenticated surfaces and cross-references any discovered API key patterns in responses with the submitted OpenAPI spec to identify insecure usage. For instance, if a FastAPI route returns a Firestore document containing a field named api_key or secret, and that route lacks proper authorization, this becomes a high-severity finding. The scanner validates input validation weaknesses and rate limiting gaps that can enable enumeration or credential harvesting when Firestore is used as the backend.
Firestore-Specific Remediation in Fastapi — concrete code fixes
Remediation centers on strict separation between server-side code and client-side access, hardened Firestore rules, and disciplined handling of secrets in FastAPI. Never embed API keys or service account JSON in application code or container images. Use Google Cloud’s default application credentials on the server and restrict Firestore rules to the narrowest necessary permissions.
On the FastAPI side, keep all sensitive operations server-side. Use environment variables injected by a secure runtime (not checked into source control) and validate all inputs before using them in Firestore queries. Below is a secure FastAPI route that retrieves user-specific documents without exposing keys to the client and avoids leaking document paths through errors.
from fastapi import FastAPI, HTTPException, Depends
from google.cloud import firestore
import os
from pydantic import BaseModel
app = FastAPI()
# Rely on Application Default Credentials in production (e.g., Cloud Run, GKE, Cloud Functions).
# Do not embed credentials in code or environment variables containing raw keys.
db = firestore.Client()
class UserProfile(BaseModel):
display_name: str
email: str
@app.get("/users/{user_id}")
def get_user_profile(user_id: str):
# Validate and sanitize user_id to prevent NoSQL injection or path traversal.
if not user_id or not user_id.isalnum():
raise HTTPException(status_code=400, detail="Invalid user identifier")
try:
doc_ref = db.collection("users").document(user_id)
doc = doc_ref.get()
if not doc.exists:
raise HTTPException(status_code=404, detail="User not found")
data = doc.to_dict()
# Never return raw API keys or internal secrets.
data.pop("api_key", None)
data.pop("service_account_secret", None)
return data
except Exception as e:
# Avoid exposing stack traces or internal paths in responses.
raise HTTPException(status_code=500, detail="Internal server error")
On the Firestore rules side, enforce principle of least privilege. The following rules restrict users to their own document paths and deny public reads/writes. These rules assume authentication is enforced by Firebase Auth or an identity provider integrated with FastAPI.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
// Explicitly deny public access.
allow read, write: if false;
}
// Deny collection group wildcard access unless intentionally required.
match /{document=**} {
allow read, write: if false;
}
}
}
Additionally, configure FastAPI to rotate and scope credentials using IAM roles rather than long-lived keys. If a key must be used for downstream services, store it in a secrets manager and inject it at runtime. middleBrick’s Pro plan supports continuous monitoring for such exposures, and the GitHub Action can fail builds if insecure patterns are detected in OpenAPI specs or runtime responses. The MCP Server enables rapid scanning from your IDE when iterating on Firestore integrations, helping catch key exposure before deployment.
Finally, validate that error messages do not echo raw Firestore exceptions, which may include collection or document paths that aid attackers. Use generic error responses and log detailed issues server-side only. Combine these practices with input validation and rate limiting to reduce enumeration risks and ensure that exposed surfaces remain minimal.