Header Injection in Fastapi with Hmac Signatures
Header Injection in Fastapi with Hmac Signatures — how this specific combination creates or exposes the vulnerability
Header Injection in FastAPI when HMAC signatures are used for integrity and authentication can occur when an attacker is able to inject or manipulate HTTP headers that influence how the signature is verified. FastAPI applications commonly rely on HMAC-signed headers (e.g., X-API-Signature) to ensure that requests have not been tampered with. If the application includes attacker-controlled headers in the data that is signed, or if the signature verification logic does not strictly limit which headers are included, an attacker may be able to inject headers that change the canonical string that is signed.
Consider a FastAPI service that signs a request using a subset of headers such as X-API-Key and X-Request-Timestamp. If the application adds all incoming headers indiscriminately into the signature base string, an attacker could inject a header like X-Forwarded-For or X-Original-URL that alters the signed payload. Because HMAC is deterministic, the altered header changes the expected signature, and if the server incorrectly normalizes or includes untrusted headers during verification, it may accept a modified request as valid. This can lead to security-relevant consequences such as bypassing intended routing, impersonation, or privilege escalation.
Another scenario involves case-insensitive header names and duplicate headers. HTTP header names are case-insensitive, but some frameworks preserve the original casing. If the canonicalization step does not normalize header names to a consistent case (e.g., lowercasing), an attacker might supply X-Api-Signature and X-API-Signature as separate headers, leading to mismatched verification logic. Similarly, if duplicate headers are handled inconsistently between the client and the server, the set of headers included in the HMAC computation may differ from what the client expects, enabling injection by manipulating which headers are serialized into the signed string.
In FastAPI, middleware or dependency injection logic that reads headers must be careful not to incorporate untrusted or user-supplied headers into the signed material unless they are explicitly expected and validated. For instance, including headers like Referer or Origin, which can be influenced by the client or by intermediaries, in the HMAC computation introduces risk. An attacker may leverage these mutable headers to forge requests that appear to carry a valid signature, especially when the server’s verification does not strictly whitelist required headers and reject unexpected ones.
Real-world attack patterns mirror common web vulnerabilities such as injection and tampering, mapping to the OWASP API Top 10’s Broken Object Level Authorization and Security Misconfiguration. Although HMAC protects integrity, incorrect usage in FastAPI can weaken its protections. For example, if a developer signs a concatenation of method, path, and a dynamic header like X-Custom-Value without validating that header’s content, an attacker may modify X-Custom-Value to alter business logic outcomes while preserving a valid signature. This underscores the importance of strictly defining which headers participate in signing and ensuring that header values are validated before inclusion in the HMAC base string.
Hmac Signatures-Specific Remediation in Fastapi — concrete code fixes
Remediation focuses on strict header whitelisting, canonicalization, and secure signature verification in FastAPI. Do not include mutable or client-influenced headers in the signed payload. Instead, define a small, immutable set of headers required for the operation (e.g., X-API-Key, X-Request-Timestamp, X-Nonce) and enforce their presence and format before computing or verifying the HMAC.
Below is a secure example of HMAC verification in FastAPI that demonstrates these practices. It uses a whitelist of headers, enforces lowercase canonicalization, and avoids incorporating untrusted data into the signed string.
import hashlib
import hmac
from fastapi import FastAPI, Request, HTTPException, Header
from typing import List
app = FastAPI()
# Whitelist of headers allowed to participate in HMAC signing
ALLOWED_HEADERS = {"x-api-key", "x-request-timestamp", "x-nonce"}
SECRET_KEY = b"super-secret-key"
def compute_hmac(method: str, path: str, headers: dict) -> str:
# Build canonical header string from whitelisted, lowercased headers
canonical_parts = []
for name in sorted(ALLOWED_HEADERS):
value = headers.get(name, "")
# Ensure consistent formatting; trim and use raw values without extra whitespace
canonical_parts.append(f"{name}:{value}")
message = "\n".join([f"{method}", path] + canonical_parts)
return hmac.new(SECRET_KEY, message.encode("utf-8"), hashlib.sha256).hexdigest()
@app.post("/webhook")
async def handle_webhook(
request: Request,
x_api_key: str = Header(...),
x_request_timestamp: str = Header(...),
x_nonce: str = Header(...)
):
# Validate required headers individually before verification
if not x_api_key or not x_request_timestamp or not x_nonce:
raise HTTPException(status_code=400, detail="Missing required headers")
# Compute expected signature using only whitelisted headers
expected_signature = compute_hmac(request.method, request.url.path, request.headers)
provided_signature = request.headers.get("X-API-Signature", "")
# Use constant-time comparison to avoid timing attacks
if not hmac.compare_digest(expected_signature, provided_signature):
raise HTTPException(status_code=401, detail="Invalid signature")
# Additional business logic here
return {"status": "ok"}
This example ensures that only explicitly allowed headers are included in the HMAC computation, header names are normalized to lowercase, and the signature comparison is performed in constant time. It avoids concatenating arbitrary headers and mitigates injection risks related to header manipulation.
In production, you should also validate the format and freshness of timestamp and nonce headers to prevent replay attacks, and store the secret key securely outside of application code. Using environment variables or a secrets manager is recommended. For applications that already use the middleBrick CLI to scan APIs, integrating these checks into your development workflow can help catch misconfigurations before deployment.
If you prefer an automated workflow, the middleBrick GitHub Action can add API security checks to your CI/CD pipeline and fail builds if risk scores exceed your threshold. This complements secure coding practices by providing continuous feedback on API configurations, including issues related to authentication mechanisms like HMAC usage.