HIGH prototype pollutionfastapihmac signatures

Prototype Pollution in Fastapi with Hmac Signatures

Prototype Pollution in Fastapi with Hmac Signatures — how this specific combination creates or exposes the vulnerability

Prototype pollution in FastAPI applications becomes particularly concerning when HMAC signatures are used to validate request integrity. In this context, the server typically receives a JSON payload and an HMAC signature, verifies the signature, and then deserializes and processes the data. If the application merges user-controlled input into a shared object prototype before validation or in a way that the signature does not cover all merged properties, an attacker can inject properties that affect object behavior downstream.

Consider a FastAPI endpoint that accepts configuration updates. The client sends {"__proto__": {"isAdmin": true}, "data": "example"} along with an HMAC computed over the JSON string. If the server computes the HMAC over the raw body before normalizing keys (e.g., before a recursive de-proto-typization step), and then merges user-provided fields into a base object, the injected __proto__ property can modify the prototype of constructed objects. Because the HMAC did not protect the merged structure, the server may treat the tampered object as valid after signature verification.

This combination exposes a BOLA/IDOR-like risk: the attacker manipulates object inheritance or shared templates, leading to unauthorized behavior such as privilege escalation or data leakage. For example, if FastAPI models or Pydantic models rely on class-level defaults defined on prototypes, polluted properties can override those defaults silently. Input validation that checks field format but not prototype contamination will pass, while the runtime behavior changes in memory. The vulnerability is not in HMAC itself, which correctly ensures integrity of the transmitted bytes, but in how the application handles object construction after verification and whether the signed scope fully covers the merged data structure.

An attacker may also attempt nested pollution via arrays or deeply nested objects, expecting the server to recursively merge or extend prototypes. If the application uses utility functions that iterate over keys and assign them directly onto a shared object, and the HMAC scope excludes those runtime merges, the signature remains valid while the object’s behavior changes. This pattern aligns with classic prototype pollution chains known from JavaScript environments, but can manifest in Python when object models expose mutable class-level attributes.

Hmac Signatures-Specific Remediation in Fastapi — concrete code fixes

To mitigate prototype pollution while using HMAC signatures in FastAPI, ensure that the signed scope covers all data used for object construction and that incoming payloads are normalized before merging. Below are concrete, working code examples demonstrating a secure approach.

Example 1: Verify HMAC over the raw body, then sanitize and validate

import hashlib
import hmac
from fastapi import FastAPI, Request, HTTPException
from pydantic import BaseModel, Field
import json

app = FastAPI()

SECRET = b'super-secret-key'

def verify_hmac(raw_body: bytes, signature: str) -> bool:
    expected = hmac.new(SECRET, raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature)

class Payload(BaseModel):
    data: str = Field(..., min_length=1)
    # Avoid untrusted keys that can pollute prototypes

@app.post('/submit')
async def submit(request: Request):
    raw_body = await request.body()
    sig = request.headers.get('X-Signature')
    if not sig or not verify_hmac(raw_body, sig):
        raise HTTPException(status_code=401, detail='Invalid signature')

    # Parse after verification to avoid tampering before checks
    body = json.loads(raw_body)

    # Remove or reject known pollution keys before object construction
    pollution_keys = {'__proto__', 'constructor', 'prototype'}
    sanitized = {k: v for k, v in body.items() if k not in pollution_keys}

    # Validate with Pydantic to enforce types and constraints
    payload = Payload(**sanitized)
    return {'status': 'ok', 'data': payload.data}

Example 2: Canonicalize before signing and include all merged fields

import hashlib
import hmac
import json
from fastapi import FastAPI, Request, HTTPException
from pydantic import BaseModel

app = FastAPI()
SECRET = b'super-secret-key'

def canonical_json(obj) -> bytes:
    # Deterministic serialization to prevent signature mismatch
    return json.dumps(obj, sort_keys=True, separators=(',', ':')).encode()

def verify_canonical(canonical: bytes, signature: str) -> bool:
    expected = hmac.new(SECRET, canonical, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature)

class UpdateModel(BaseModel):
    setting: str
    value: str

@app.put('/config/{id}')
async def update_config(id: str, request: Request):
    raw_body = await request.body()
    sig = request.headers.get('X-Signature')
    if not sig or not verify_canonical(raw_body, sig):
        raise HTTPException(status_code=401, detail='Invalid signature')

    data = json.loads(raw_body)
    # Explicitly map to model; do not merge into global/shared objects
    update = UpdateModel(**data)
    # Apply update to target configuration without prototype-style merging
    # e.g., config_store[update.setting] = update.value
    return {'setting': update.setting, 'value': update.value}

Key remediation practices:

  • Compute HMAC over the exact bytes you intend to validate, and avoid including mutable external state in the scope.
  • Reject or strip keys commonly used for prototype pollution (__proto__, constructor, prototype) before object construction.
  • Use deterministic serialization (sorted keys, canonical separators) when the signature must cover serialized data.
  • Prefer explicit models (Pydantic) and avoid merging untrusted input into shared or global objects.
  • Treat HMAC as integrity protection, not as a substitute for input validation and schema enforcement.

Frequently Asked Questions

Does middleBrick detect prototype pollution in FastAPI endpoints protected by HMAC?
middleBrick scans unauthenticated attack surfaces and tests input validation and object handling patterns. It can identify indicators such as missing pollution-key sanitization and weak signature scope that may lead to prototype pollution in FastAPI APIs, including those using Hmac Signatures, and reports findings with remediation guidance.
Can HMAC alone prevent prototype pollution in FastAPI APIs?
HMAC ensures integrity of the transmitted payload but does not prevent prototype pollution by itself. If the server merges user-controlled keys into objects before validation or uses non-deterministic parsing, pollution paths may still be exploitable even when the HMAC verifies. Proper input sanitization and canonical handling are required alongside signature verification.