Denial Of Service in Fastapi with Hmac Signatures
Denial Of Service in Fastapi with Hmac Signatures — how this specific combination creates or exposes the vulnerability
When Fastapi endpoints are protected only by Hmac Signatures, certain DoS patterns can emerge because the signature verification step runs before resource-intensive operations. If the verification logic is computationally heavy or not bounded, an attacker can craft many valid-looking requests that force the server to perform expensive cryptographic work, consuming CPU time and thread capacity. Even when the signature itself is valid, the server may still allocate memory for payloads, database sessions, or downstream connections before rejecting the request, leading to resource exhaustion under high request rates.
Another vector specific to Hmac Signatures is the misuse of body-stream hashing. In Fastapi, reading request.body() consumes the stream; if signature verification reads the full body and later route handlers also attempt to read it without proper buffering, the second read may block or fail, causing hangs that resemble DoS. Additionally, replay attacks—where an attacker replays previously captured signed requests—can saturate rate-limiting counters or exhaust connection pools if the server does not deduplicate or short-circuit repeated signed payloads efficiently.
Middleware that verifies Hmac Signatures synchronously in the request path can block the event loop in cases where CPU-bound hashing is performed without offloading to a thread pool. Fastapi, based on Starlette, runs request handling in an async context; if cryptographic operations are not async-friendly or are performed on large payloads in the main loop, response times increase and the server becomes less able to accept new connections, effectively creating a self-inflicted DoS condition.
Real-world attack patterns mirror CVE-style scenarios where signed endpoints without payload size limits or request-cost controls allow an adversary to submit large JSON or file uploads with valid Hmac headers, causing memory and CPU spikes. Although middleBrick does not fix or block, its scans can highlight missing request-size caps, absence of stream buffering, and lack of per-client rate limits as findings that correlate with DoS risk under the Authentication and Rate Limiting checks.
To detect these issues in practice, scans should exercise endpoints with varying payload sizes and repeated nonces while monitoring response latency and error rates. Findings often include recommendations to enforce strict content-length limits, validate signatures on a copy of the body, and use short-lived nonces or timestamps to prevent replays—controls that reduce the attack surface without altering the core Hmac scheme.
Hmac Signatures-Specific Remediation in Fastapi — concrete code fixes
Implement Hmac verification in a way that minimizes CPU and memory pressure. Compute the signature on a bounded, known subset of headers and a fixed-size body excerpt when possible, and avoid reading the request body multiple times. Use async-compatible cryptography libraries and enforce strict request-size and rate limits before heavy computation.
Example secure Fastapi middleware with Hmac Signatures:
import time
import hmac
import hashlib
from fastapi import FastAPI, Request, HTTPException, Depends
from fastapi.responses import JSONResponse
app = FastAPI()
SECRET_KEY = b'your-secure-secret-key-change-this'
MAX_BODY_SIZE = 1024 * 128 # 128 KiB cap
def verify_hmac(request: Request) -> bool:
timestamp = request.headers.get('X-Timestamp')
nonce = request.headers.get('X-Nonce')
signature = request.headers.get('X-Signature')
if not all([timestamp, nonce, signature]):
return False
# Reject old timestamps to prevent replay
if abs(time.time() - int(timestamp)) > 30:
return False
# Read body safely with a size cap
body = request.body()
if len(body) > MAX_BODY_SIZE:
return False
message = timestamp.encode() + nonce.encode() + body
expected = hmac.new(SECRET_KEY, message, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature)
@app.middleware('http')
async def hmac_middleware(request: Request, call_next):
if request.method in ('POST', 'PUT', 'PATCH'):
if not verify_hmac(request):
raise HTTPException(status_code=401, detail='Invalid signature')
response = await call_next(request)
return response
@app.post('/data')
async def ingest(data: dict):
return JSONResponse({'status': 'ok'})
Key remediation points illustrated:
- Body size limit prevents memory exhaustion from large uploads.
- Timestamp and nonce mitigate replay attacks that could saturate endpoints.
- Signature computed over a bounded message to keep CPU usage predictable.
- Use of
hmac.compare_digestto avoid timing attacks that could be leveraged for indirect DoS via repeated probes.
For high-throughput services, offload signature verification to a dedicated worker or thread pool to avoid blocking the async event loop, and ensure per-client rate limits are applied before verification to drop abusive traffic early. middleBrick’s scans can surface missing limits and weak validation patterns as high-severity findings tied to Authentication and Rate Limiting checks.
Related CWEs: resourceConsumption
| CWE ID | Name | Severity |
|---|---|---|
| CWE-400 | Uncontrolled Resource Consumption | HIGH |
| CWE-770 | Allocation of Resources Without Limits | MEDIUM |
| CWE-799 | Improper Control of Interaction Frequency | MEDIUM |
| CWE-835 | Infinite Loop | HIGH |
| CWE-1050 | Excessive Platform Resource Consumption | MEDIUM |