HIGH auth bypassfastapihmac signatures

Auth Bypass in Fastapi with Hmac Signatures

Auth Bypass in Fastapi with Hmac Signatures — how this specific combination creates or exposes the vulnerability

HMAC-based authentication in FastAPI can lead to an authentication bypass when the server-side verification logic is incomplete, inconsistent, or applied only to selected endpoints. A common pattern is to compute a signature on the client using a shared secret and a canonical representation of the request (method, path, selected headers, and body), then send the signature in a custom header such as X-API-Signature. The server is expected to recompute the signature using the same canonicalization and secret, and to reject the request if the signatures do not match.

Vulnerabilities arise when the server either skips verification for some routes, accepts multiple signature versions, or uses an unsafe comparison that is vulnerable to timing attacks. For example, if a FastAPI app applies signature verification only to POST /transfer but not to GET /account, an attacker can read sensitive data or perform actions without a valid signature. Incomplete canonicalization can also allow path or query parameter manipulation without changing the signature, enabling privilege escalation or unauthorized actions (BOLA/IDOR).

Another failure mode is treating the signature as a bearer token-like value without ensuring message integrity properties such as replay protection and timestamp validation. If the server accepts a static or weakly scoped signature, an attacker can reuse the signature across requests or sessions. Missing replay or nonce handling can turn the HMAC mechanism into a static credential that can be captured and reused, effectively bypassing authentication.

The risk is compounded when combined with other unchecked attack surfaces, such as excessive agency in LLM endpoints or unsafe consumption patterns that forward or transform requests. middleBrick detects these issues by correlating spec definitions containing security schemes with runtime behavior, highlighting cases where signature verification is missing, misconfigured, or applied inconsistently across the API surface.

Hmac Signatures-Specific Remediation in Fastapi — concrete code fixes

Remediation centers on consistent, server-side verification with a strict canonicalization method, constant-time comparison, replay/nonce controls, and applying the check to all authenticated endpoints. Below is a complete, realistic example using Python with FastAPI, the cryptography library, and standard libraries only.

import time
import hmac
import hashlib
from fastapi import FastAPI, Request, Header, HTTPException, status
from typing import Optional

app = FastAPI()

# Shared secret stored securely, e.g., from a vault or env var
SHARED_SECRET = b'example-strong-secret-change-in-production'

def canonicalize_request(method: str, path: str, timestamp: str, nonce: str, body: bytes) -> bytes:
    # Canonical format: method|path|timestamp|nonce|body
    parts = [method.upper().strip(), path.strip(), timestamp.strip(), nonce.strip(), body]
    return b'|'.join(part if isinstance(part, bytes) else part.encode('utf-8') for part in parts)

def verify_signature(request: Request, received_signature: str) -> bool:
    timestamp = request.headers.get('X-Timestamp')
    nonce = request.headers.get('X-Nonce')
    if not timestamp or not nonce:
        return False
    # Reject requests older than 5 minutes to mitigate replay
    try:
        req_time = int(timestamp)
    except ValueError:
        return False
    if abs(time.time() - req_time) > 300:
        return False
    body = request.body()
    canonical = canonicalize_request(request.method, request.url.path, timestamp, nonce, body)
    expected = hmac.new(SHARED_SECRET, canonical, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, received_signature)

@app.middleware('http')
async def verify_hmac_signature(request: Request, call_next):
    # Apply to all routes that require authentication; adjust paths as needed
    if request.url.path.startswith('/api/'):
        signature = request.headers.get('X-API-Signature')
        if not signature or not verify_signature(request, signature):
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail='Invalid or missing signature'
            )
    response = await call_next(request)
    return response

@app.post('/transfer')
async def transfer(request: Request):
    return {'status': 'ok'}

@app.get('/account')
async def account(request: Request):
    return {'account': 'data'}

Key remediation points embedded in the example:

  • Consistent canonicalization across client and server using method, path, timestamp, nonce, and body with a deterministic separator.
  • Timestamp and nonce checks to prevent replay attacks; reject requests older than a short window (e.g., 300 seconds).
  • Use of hmac.compare_digest for constant-time signature comparison to avoid timing-based leakage.
  • Applying the verification middleware to all authenticated routes, avoiding selective enforcement that leads to BOLA/IDOR or privilege escalation.
  • Keeping the shared secret out of source code and loading it from a secure configuration or vault.

For more complex scenarios, include a versioned signature algorithm header (e.g., X-Signature-Algorithm) and reject unknown versions. Ensure that any body parsing (e.g., JSON) is performed before canonicalization and that the raw body is used to avoid mismatches caused by serialization differences.

middleBrick can validate these practices by checking spec-defined security schemes against runtime behavior, ensuring that required authentication is enforced uniformly and that findings are mapped to frameworks such as OWASP API Top 10 and PCI-DSS.

Related CWEs: authentication

CWE IDNameSeverity
CWE-287Improper Authentication CRITICAL
CWE-306Missing Authentication for Critical Function CRITICAL
CWE-307Brute Force HIGH
CWE-308Single-Factor Authentication MEDIUM
CWE-309Use of Password System for Primary Authentication MEDIUM
CWE-347Improper Verification of Cryptographic Signature HIGH
CWE-384Session Fixation HIGH
CWE-521Weak Password Requirements MEDIUM
CWE-613Insufficient Session Expiration MEDIUM
CWE-640Weak Password Recovery HIGH

Frequently Asked Questions

Which parts of the request should be included in the HMAC canonicalization to reduce the risk of auth bypass?
Include the HTTP method, request path, a timestamp, a nonce, and the raw request body. Use a deterministic separator and ensure the server uses the exact same canonicalization; avoid omitting query parameters or headers that affect processing, and reject requests with missing or mismatched components.
How can replay attacks be mitigated when using Hmac Signatures in FastAPI?
Add a timestamp (X-Timestamp) and a nonce (X-Nonce) to each request, verify the timestamp is within a short window (for example 300 seconds), and maintain a short-lived cache of recently seen nonces to reject duplicates. Enforce these checks in a server-side middleware that applies to all authenticated endpoints.