HIGH crlf injectionfastapihmac signatures

Crlf Injection in Fastapi with Hmac Signatures

Crlf Injection in Fastapi with Hmac Signatures — how this specific combination creates or exposes the vulnerability

Crlf Injection occurs when an attacker can inject carriage return (CR, \r) and line feed (\n) characters into a header or status-line value. In Fastapi, if user-controlled data is reflected in HTTP headers or the status line and those values are not strictly validated or encoded, an attacker can chain headers or split responses. This becomes particularly relevant when Hmac Signatures are used for request authentication and integrity: the signature is typically computed over selected headers and a method/path, and the server recomputes and compares it. If an attacker can inject a header via CRLF, they can smuggle an additional header that changes the set of signed headers or the request target seen by the server, leading to request smuggling, response splitting, or bypass of intended authorization checks.

For example, consider a Fastapi endpoint that uses a custom header X-Request-ID for idempotency and includes that header in the Hmac signature. An attacker could provide a value like abc\r\nX-Internal: override. If the server concatenates this value into the signature base without normalization, the injected header may be processed separately, potentially altering behavior or bypassing logic that depends on a single, expected header. In other scenarios, CRLF in a URL parameter that is later reflected in a Location header can cause open redirects or cache poisoning. Because Hmac Signatures bind specific headers and the request target, unchecked injection can undermine the integrity guarantees the signature is meant to provide.

Fastapi does not automatically sanitize header values; it relies on the underlying Starlette/ASGI server to parse messages. If the application directly uses request headers in signature computation or response construction without canonicalization and strict validation, the unauthenticated attack surface includes header manipulation. Tools such as middleBrick scan these unauthenticated surfaces and flag header injection risks among the 12 parallel security checks, highlighting findings tied to input validation and property authorization that can intersect with signature misuse.

Hmac Signatures-Specific Remediation in Fastapi — concrete code fixes

To mitigate Crlf Injection when using Hmac Signatures in Fastapi, ensure that any data used to compute or verify the signature is canonicalized and that header values are strictly validated and encoded. Do not directly concatenate raw user input into the signature base. Instead, normalize inputs, reject or encode CR/LF characters, and use a robust method for header selection and hashing.

Below is a concrete, working example of a Fastapi middleware that validates headers and computes Hmac signatures safely. It rejects header values containing CR or LF, selects a canonical set of headers for signing, and uses hashlib and hmac from the standard library.

from fastapi import Fastapi, Request, Header, HTTPException, Response
from fastapi.middleware import Middleware
from fastapi.middleware.base import BaseHTTPMiddleware
import hmac
import hashlib
import base64
import re

app = Fastapi()

# A simple in-memory secret; use a secure secret store in production
SECRET = b"super-secret-key"

# Canonical header names to include in the signature; keep this ordered
CANONICAL_HEADERS = ["x-request-id", "content-type"]

# Reject unsafe characters in header values
UNSAFE_HEADER_RE = re.compile(r"[\r\n]")

def validate_header_value(value: str) -> None:
    if UNSAFE_HEADER_RE.search(value):
        raise ValueError("Header value contains disallowed CR/LF characters")

class HmacSignatureMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        # Validate incoming headers used in signing
        for header in CANONICAL_HEADERS:
            value = request.headers.get(header, "")
            if value and UNSAFE_HEADER_RE.search(value):
                raise HTTPException(status_code=400, detail=f"Invalid header value for {header}")

        # Compute signature over canonical headers
        parts = []
        for h in CANONICAL_HEADERS:
            val = request.headers.get(h, "")
            # Use a consistent format: lowercased header name and trimmed value
            parts.append(f"{h.lower()}:{val.strip()}")
        body = await request.body()
        payload = "\n".join(parts).encode() + b"\n" + body
        computed = hmac.new(SECRET, payload, hashlib.sha256).digest()
        signature = base64.b64encode(computed).decode()

        # Optionally verify an incoming signature (example: X-Signature header)
        incoming = request.headers.get("X-Signature")
        if incoming:
            if not hmac.compare_digest(incoming, signature):
                raise HTTPException(status_code=401, detail="Invalid signature")

        response = await call_next(request)
        # Example of safely setting a response header; ensure values are validated
        response.headers["X-Request-Id"] = request.headers.get("X-Request-Id", "")
        return response

app.add_middleware(HmacSignatureMiddleware)

@app.get("/items/{item_id}")
async def read_item(
    item_id: int,
    x_request_id: str = Header(None, alias="X-Request-ID")
):
    return {"item_id": item_id, "x_request_id": x_request_id}

Key remediation steps in this example:

  • Canonical header selection: only specific headers are included in the signature base, in a fixed order.
  • Input validation: header values are checked for CR/LF before use, preventing response splitting or header injection.
  • Consistent formatting: header names are normalized to lowercase and values are stripped to reduce variability.
  • Secure comparison: signatures are compared using hmac.compare_digest to avoid timing attacks.

In production, rotate secrets, store them securely, and align the canonical header list with the actual API contract. middleBrick’s scans can highlight mismatches between documented headers and those included in the signature, as well as flag unsafe reflection patterns that could enable CRLF-based bypasses.

Frequently Asked Questions

Can CRLF injection bypass Hmac Signature validation in Fastapi?
Yes, if user-controlled data is reflected in headers used for signing without validation, an attacker can inject additional headers or split responses, potentially altering the signed set and undermining the signature's integrity.
How does middleBrick relate to CRLF and Hmac Signature issues?
middleBrick scans unauthenticated attack surfaces and flags input validation and property authorization findings, including header injection risks that can intersect with Hmac Signature misuse.