HIGH prototype pollutionfastapiapi keys

Prototype Pollution in Fastapi with Api Keys

Prototype Pollution in Fastapi with Api Keys — how this specific combination creates or exposes the vulnerability

Prototype pollution in FastAPI contexts where API keys are used for authentication involves both runtime behavior and API design. When a FastAPI endpoint accepts user input—such as JSON payloads, query parameters, or headers—and merges that input into application or framework-level objects, it can inadvertently modify the prototype of shared objects. This commonly occurs when user-controlled keys are used to update dictionaries or settings that are reused across requests.

Consider a FastAPI application that uses API keys passed via an Authorization: ApiKey <key> header. If the application validates the key and then stores per-request state by updating a global dictionary with values derived from the request, an attacker can supply crafted keys such as __proto__, constructor, or other special properties that affect object inheritance chains. For example:

from fastapi import FastAPI, Header, HTTPException

app = FastAPI()
api_keys = {"abc123": "alice", "def456": "bob"}

@app.get("/items")
def read_items(x_api_key: str = Header(None)):
    if x_api_key not in api_keys:
        raise HTTPException(status_code=401, detail="Invalid key")
    # Unsafe merge: attacker can pollute app-level state
    state = {"user": api_keys[x_api_key]}
    for k, v in request_body.items():  # hypothetical unsafe merge
        state[k] = v
    return state

If an attacker sends a payload containing { "__proto__": { "isAdmin": true } }, and the application merges this into a shared object or class prototype, the pollution can lead to privilege escalation or data leakage across requests. In FastAPI, this often surfaces when developers inadvertently treat user input as trusted configuration or merge it into objects that persist beyond the request lifecycle.

The API key mechanism itself does not cause prototype pollution, but it can amplify impact: a single compromised or leaked API key may grant an attacker a foothold to explore or manipulate object prototypes if the application uses the key to index into shared mutable structures. Moreover, if API keys are logged, exposed in error messages, or reflected in responses, they can aid reconnaissance for prototype pollution vectors that rely on parameter names or paths.

Because middleBrick scans unauthenticated attack surfaces, it can detect endpoints that accept input and inspect whether responses reflect manipulated object properties indicative of prototype pollution. Findings will highlight risky patterns such as unchecked merging of user input into global or shared objects, and they map to OWASP API Top 10 and related compliance frameworks.

Api Keys-Specific Remediation in Fastapi — concrete code fixes

Remediation focuses on preventing user input from modifying object prototypes and ensuring API key handling remains isolated and immutable. Below are concrete, safe patterns for FastAPI applications using API keys.

1. Use explicit models and avoid dynamic merging. Define Pydantic models for incoming data and exclude fields that could influence prototypes.

from fastapi import FastAPI, Header, HTTPException
from pydantic import BaseModel

app = FastAPI()
api_keys = {"abc123": "alice", "def456": "bob"}

class ItemInput(BaseModel):
    name: str
    quantity: int
    # Do not include fields like __proto__, constructor, or other special keys

@app.post("/items")
def create_item(body: ItemInput, x_api_key: str = Header(None)):
    if x_api_key not in api_keys:
        raise HTTPException(status_code=401, detail="Invalid key")
    # Safe: body is validated and cannot contain prototype-influencing properties
    return {"user": api_keys[x_api_key], "item": body.dict()}

2. Normalize and filter input keys. If you must work with dynamic dictionaries, strip dangerous keys before merging.

import copy

def safe_merge(base, updates):
    dangerous = {"__proto__", "constructor", "prototype"}
    filtered = {k: v for k, v in updates.items() if k not in dangerous}
    result = copy.deepcopy(base)
    result.update(filtered)
    return result

@app.post("/merge")
def merge_data(base: dict, x_api_key: str = Header(None)):
    if x_api_key not in api_keys:
        raise HTTPException(status_code=401, detail="Invalid key")
    # Assume `payload` comes from request body; filter before merge
    merged = safe_merge(base, request_body)
    return merged

3. Keep API key validation and state isolated. Avoid storing per-request state in global structures that could be polluted.

from fastapi import Depends

def get_current_user(x_api_key: str = Header(None)):
    if x_api_key not in api_keys:
        raise HTTPException(status_code=401, detail="Invalid key")
    return api_keys[x_api_key]

@app.get("/profile")
def get_profile(user: str = Depends(get_current_user)):
    # user is derived from API key; no merging with request input
    return {"user": user}

Using middleBrick’s CLI, you can regularly scan your endpoints to verify that such safe patterns are in place: middlebrick scan https://api.example.com. The CLI outputs JSON and text reports that highlight findings tied to input validation and authentication. For CI/CD integration, the GitHub Action can enforce a maximum risk score, failing builds if unsafe patterns are detected before deployment.

Frequently Asked Questions

Can API keys alone prevent prototype pollution in FastAPI?
No. API keys handle authentication but do not prevent prototype pollution. Pollution occurs when user-controlled keys or input are merged into shared objects. You must validate and filter input and avoid dynamic merging into prototypes regardless of authentication.
How does middleBrick detect prototype pollution risks in FastAPI APIs using API keys?
middleBrick performs black-box scanning of the unauthenticated attack surface and analyzes OpenAPI specs with full $ref resolution. It checks for endpoints that accept mutable input and inspect runtime responses for signs of reflected or manipulable object properties, reporting findings with severity and remediation guidance.