HIGH prototype pollutionfastapibasic auth

Prototype Pollution in Fastapi with Basic Auth

Prototype Pollution in Fastapi with Basic Auth — how this specific combination creates or exposes the vulnerability

Prototype pollution in FastAPI with Basic Auth occurs when user-controlled input used to update dictionaries or objects flows through an API endpoint that also relies on HTTP Basic Authentication for access control. FastAPI does not automatically protect against prototype pollution; if a route merges or updates a dictionary using data from the request (e.g., request body or query parameters) and that route is protected only by Basic Auth, an attacker can supply crafted keys such as __proto__, constructor, or other special properties to mutate shared objects. Because Basic Auth typically provides identity but not schema validation, the server may trust the authenticated request and propagate the polluted prototype to downstream logic, configuration, or template rendering.

Consider an endpoint that builds a response by copying user input into a base dictionary:

from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import HTTPBasic, HTTPBasicCredentials
import copy

app = FastAPI()
security = HTTPBasic()

def get_current_user(credentials: HTTPBasicCredentials = Depends(security)):
    # naive check for example
    if credentials.username == 'admin' and credentials.password == 'secret':
        return {'username': credentials.username}
    raise HTTPException(status_code=401, detail='Invalid credentials')

BASE = {'debug': False, 'threshold': 10}

@app.post('/configure')
def configure(payload: dict, user: dict = Depends(get_current_user)):
    merged = copy.copy(BASE)
    merged.update(payload)  # vulnerable if payload contains __proto__-like keys
    return merged

An authenticated request with { "__proto__": { "debug": true } } can alter the prototype of objects used elsewhere in the process, leading to unexpected behavior such as bypassing debug flags or escalating permissions. In a real-world scenario, polluted prototypes can affect configuration objects, logging settings, or serialization logic. When combined with OpenAPI/Swagger spec analysis, such unsafe merges may be flagged because the spec does not enforce a safe schema, and runtime findings can reveal that authenticated endpoints remain susceptible if input validation is omitted. This illustrates why authentication alone is insufficient to prevent prototype pollution: the attack surface is defined by how the application handles structured input, not merely whether credentials are presented.

Additionally, if the API consumes OpenAPI specs with $ref resolution and dynamically generates models or validation logic, prototype-prone merge patterns can propagate across resolved definitions. The scanner’s checks for Unsafe Consumption and Input Validation highlight these risks by correlating spec definitions with runtime behavior, ensuring that authenticated endpoints are not mistakenly assumed to be safe from injection of malicious properties.

Basic Auth-Specific Remediation in Fastapi — concrete code fixes

Remediation focuses on strict input validation, avoiding prototype-mutable operations, and ensuring authentication is complemented by schema enforcement. Do not rely on Basic Auth to sanitize input; instead validate and transform data explicitly.

  • Use Pydantic models to define expected fields and reject unknown keys, which prevents pollution by disallowing __proto__ and other dangerous properties.
  • Prefer immutable updates (e.g., creating new dictionaries) over mutating shared prototypes.
  • Apply allowlists for keys and sanitize nested structures before merging.

Secure example using a Pydantic model and immutable update pattern:

from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import HTTPBasic, HTTPBasicCredentials
from pydantic import BaseModel, Field, validator
from typing import Dict, Any
import copy

app = FastAPI()
security = HTTPBasic()

class ConfigPayload(BaseModel):
    debug: bool = Field(default=False)
    threshold: int = Field(default=10, ge=0, le=100)

    @validator('*')
    def prevent_proto_pollution(cls, v, field):
        # reject keys that could influence prototypes in common runtimes
        if field.name in ('__proto__', 'constructor', 'prototype'):
            raise ValueError(f'Invalid field name: {field.name}')
        return v

def get_current_user(credentials: HTTPBasicCredentials = Depends(security)):
    if credentials.username == 'admin' and credentials.password == 'secret':
        return {'username': credentials.username}
    raise HTTPException(status_code=401, detail='Invalid credentials')

BASE = {'debug': False, 'threshold': 10}

@app.post('/configure')
def configure(payload: ConfigPayload, user: dict = Depends(get_current_user)):
    # safe immutable update using dict unpacking
    merged = {**BASE, **payload.dict()}
    return merged

If you must merge nested structures, explicitly handle them to avoid mutating shared objects:

def safe_update(base: Dict[str, Any], changes: Dict[str, Any]) -> Dict[str, Any]:
    result = base.copy()
    for key, value in changes.items():
        if key in ('__proto__', 'constructor', 'prototype'):
            continue  # drop dangerous keys
        if isinstance(value, dict) and key in result and isinstance(result[key], dict):
            result[key] = safe_update(result[key], value)
        else:
            result[key] = value
    return result

@app.post('/configure-nested')
def configure_nested(payload: dict, user: dict = Depends(get_current_user)):
    merged = safe_update(BASE, payload)
    return merged

These patterns ensure that authentication protects access while validation and safe merging protect against prototype pollution. The CLI (middlebrick scan <url>) and GitHub Action can be used to verify that endpoints using Basic Auth enforce strict schemas and avoid unsafe merges, and the MCP Server allows you to scan APIs directly from your AI coding assistant to catch such issues early in development.

Frequently Asked Questions

Does using Basic Auth in FastAPI prevent prototype pollution?
No. Basic Auth provides identity but does not validate or sanitize input. Without explicit schema enforcement and safe merge patterns, authenticated endpoints remain vulnerable to prototype pollution.
How can I detect prototype pollution risks in my FastAPI APIs that use Basic Auth?
Use middleBrick to scan endpoints; the scanner checks Input Validation and Unsafe Consumption independently of authentication. The CLI (middlebrick scan ), GitHub Action, and MCP Server can integrate checks into your workflow and highlight missing schema controls.