Timing Attack in Fastapi with Hmac Signatures
Timing Attack in Fastapi with Hmac Signatures — how this specific combination creates or exposes the vulnerability
A timing attack in a FastAPI service that uses HMAC signatures occurs when the comparison of the computed signature with the client-supplied signature does not execute in constant time. In FastAPI, this typically happens after signature verification succeeds and the application proceeds to process the request. Because the framework does not automatically enforce constant-time comparison, an attacker can measure response times to infer information about the expected HMAC, such as which bytes match and which diverge.
Consider a FastAPI endpoint that expects an HMAC-SHA256 signature passed via a header. If the developer compares signatures using a standard equality check (e.g., hmac.compare_digest(expected, actual) is correctly used), the risk is lower, but if earlier logic branches or validation steps leak timing differences, the attack surface remains. For example, checking individual fields before verifying the signature, or performing variable-cost operations (like database lookups) conditionally based on partial signature correctness, can introduce measurable timing differences.
During a black-box scan, middleBrick tests for timing-related behavior by sending many requests with slightly altered inputs and measuring response times. If the endpoint is implemented in FastAPI without constant-time safeguards around signature comparison and early validation, these tests can expose deviations that correlate with partial matches. A successful timing side-channel can allow an attacker to recover the HMAC or forge authenticated requests, undermining the integrity guarantees that HMAC is meant to provide.
Even when using strong cryptographic primitives, implementation details in FastAPI—such as middleware ordering, dependency injection, and how exceptions are handled—can inadvertently create observable timing differences. For instance, raising an early authentication failure versus proceeding to business logic can change response duration. middleBrick’s checks include observing these behavioral differences as part of its unauthenticated attack surface testing, focusing on how the API behaves when presented with valid versus invalid signatures.
In summary, the combination of FastAPI’s flexible request handling and improper signature comparison logic can expose timing-sensitive behavior. An attacker observing network latency can infer whether partial signature checks succeeded, leading to gradual information leakage. This is not a vulnerability in HMAC itself, but in how the API integrates and compares signatures within its request lifecycle.
Hmac Signatures-Specific Remediation in Fastapi — concrete code fixes
To mitigate timing attacks in FastAPI when using HMAC signatures, ensure that all signature comparisons are performed in constant time and that no early branching reveals validation state. Use hmac.compare_digest for byte or string comparisons, and avoid conditional logic that depends on partial signature correctness.
Below is a concrete, working FastAPI example that demonstrates secure handling of HMAC-SHA256 signatures. The endpoint extracts a signature from a header, computes the HMAC over the request body using a shared secret, and compares the two values safely.
import hmac
import hashlib
from fastapi import FastAPI, Request, HTTPException, status
from fastapi.responses import JSONResponse
app = FastAPI()
SHARED_SECRET = b"super-secret-key-32-bytes-long-for-demo-only" # store securely, e.g. env
def verify_hmac_signature(body: bytes, received_signature: str) -> bool:
computed = hmac.new(SHARED_SECRET, body, hashlib.sha256).hexdigest()
return hmac.compare_digest(computed, received_signature)
@app.post("/secure-data")
async def secure_data(request: Request):
body = await request.body()
received_signature = request.headers.get("X-API-Signature")
if not received_signature:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Missing signature header"
)
if not verify_hmac_signature(body, received_signature):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid signature"
)
# Proceed with business logic only after constant-time verification
return JSONResponse({"status": "ok"})
Key practices in this remediation:
- Always use
hmac.compare_digestfor signature comparison to ensure constant-time behavior. - Perform signature verification before any business logic or external calls, and avoid branching on partial validation results.
- Return a generic error message for invalid signatures to prevent information leakage via response content or timing.
- Ensure the shared secret is stored securely and is of sufficient entropy; rotate it according to your security policy.
If you use dependencies or middleware for authentication, ensure they also follow constant-time patterns and do not introduce timing leaks. middleBrick’s scans can validate that your FastAPI implementation avoids detectable timing differences by analyzing runtime behavior against crafted probes.
Frequently Asked Questions
Can a timing attack recover the full HMAC signature from a FastAPI endpoint?
hmac.compare_digest and ensuring constant-time validation logic eliminates this risk.