Stack Overflow in Fastapi with Api Keys
Stack Overflow in Fastapi with Api Keys — how this specific combination creates or exposes the vulnerability
A Stack Overflow in a FastAPI service that uses API keys typically arises when user-controlled input is used to compute or index into a data structure without length checks, allowing an attacker to consume excessive memory by sending very large payloads or deeply nested structures. When API keys are used for authentication but input validation is weak, the combination can amplify impact: an authenticated call with a valid key can still trigger resource exhaustion if the endpoint processes untrusted data (e.g., JSON, query parameters, or headers) unsafely.
Consider an endpoint that aggregates values from a JSON object by iterating over keys. If the JSON object is large or contains recursive references, and the endpoint does not enforce size or depth limits, an attacker can send a crafted payload that causes the server to grow the call stack or heap dramatically. Even with API keys in place, which confirm the caller is permitted to access the endpoint, the unchecked processing of input can degrade performance or cause crashes, leading to denial of service for legitimate users.
In FastAPI, common triggers include recursive models (Pydantic) that resolve deeply nested structures, or unchecked use of dict and list operations on user data. For example, a recursive model like:
from pydantic import BaseModel
from typing import List, Optional
class Node(BaseModel):
value: int
children: Optional[List["Node"]] = None
can lead to deep recursion if the input nesting is uncontrolled. When combined with API key authentication, an attacker who possesses a valid key can repeatedly invoke the endpoint with malicious payloads, causing stack overflows or high memory usage that affect availability.
Another scenario involves endpoints that merge path, query, and body parameters into a single processing structure without validating the overall size. Even with API keys ensuring the caller is known, the service remains vulnerable if the request body or parameters are not bounded. This is especially relevant when OpenAPI/Swagger specs do not enforce size constraints or use example fields that do not reflect real-world abuse cases.
middleBrick scans such endpoints (including those protected by API keys) and flags Stack Overflow risks under the Input Validation and Unsafe Consumption checks. It correlates runtime behavior with the spec, identifying where recursive models or unchecked collections can be abused. Findings include severity, context, and remediation guidance, helping teams understand the specific input patterns that lead to resource exhaustion.
Api Keys-Specific Remediation in Fastapi — concrete code fixes
To mitigate Stack Overflow risks in FastAPI when using API keys, apply input validation and resource bounds at the framework level, and ensure API key usage does not bypass checks.
1) Use size and recursion limits on Pydantic models
Configure models to reject overly nested or large payloads. Use model_config to set arbitrary_types_allowed cautiously and limit recursion depth:
from pydantic import BaseModel, ConfigDict, field_validator
from typing import List, Optional
class Node(BaseModel):
value: int
children: Optional[List["Node"]] = None
model_config = {
"arbitrary_types_allowed": False,
}
@field_validator("children")
@classmethod
def limit_children_depth(cls, v):
# Example guard: prevent deeply nested structures
def depth(node, current=0):
if current > 10:
raise ValueError("nesting too deep")
if node.children:
for child in node.children:
depth(child, current + 1)
if v:
for child in v:
depth(child, 0)
return v
2) Validate and bound request body size globally
Limit payload size at the middleware or dependency level to prevent large bodies from being processed even when an API key is valid:
from fastapi import FastAPI, Request, HTTPException
app = FastAPI()
@app.middleware("http")
async def limit_body_size(request: Request, call_next):
if request.method in ("POST", "PUT", "PATCH"):
body = await request.body()
if len(body) > 1_000_000: # 1 MB cap
raise HTTPException(status_code=413, detail="Payload too large")
request._body = body # preserve for downstream if needed
response = await call_next(request)
return response
3) Combine API key authentication with explicit input checks
Ensure API key dependencies validate not only the key but also the shape and size of incoming data:
from fastapi import Depends, FastAPI, HTTPException, Header
from pydantic import BaseModel
from typing import Optional
app = FastAPI()
def get_api_key(authorization: str = Header(...)):
# simplistic example; use a secure scheme in production
if authorization != "Bearer valid-key":
raise HTTPException(status_code=401, detail="Invalid API key")
return authorization
class Item(BaseModel):
name: str
tags: list[str] = []
model_config = {"max_array_length": 100, "max_field_length": 200}
@app.post("/items")
async def create_item(item: Item, api_key: str = Depends(get_api_key)):
# API key validated; input size and structure also validated by Pydantic
return {"received": item.name, "tags_count": len(item.tags)}
4) Use FastAPI’s built-in validation features
Configure max_array_length, max_str_length, and custom validators to enforce bounds that mitigate Stack Overflow risks. The OpenAPI spec generated will reflect these constraints, enabling middleBrick to cross-reference runtime behavior against the spec during scans.
These remediation steps ensure that API keys provide access control without exposing the service to resource exhaustion through unchecked input.