HIGH header injectionfastapi

Header Injection in Fastapi

How Header Injection Manifests in Fastapi

Header injection vulnerabilities in Fastapi applications occur when user-controlled data flows into HTTP response headers without proper validation or encoding. Fastapi's asynchronous nature and dependency injection system create unique attack vectors that developers must understand.

The most common Fastapi header injection pattern involves response headers constructed from request parameters or path variables. Consider this vulnerable Fastapi endpoint:

from fastapi import FastAPI, Request

app = FastAPI()

@app.get("/api/user/{user_id}")
async def get_user(request: Request, user_id: str):
    # Vulnerable: user_id flows directly into response header
    response = JSONResponse(
        content={"message": "User data"},
        headers={"X-User-ID": user_id}
    )
    return response

An attacker can exploit this by requesting /api/user/123%0D%0AX-Injected: malicious. The %0D%0A sequence represents CRLF (carriage return + line feed), which breaks out of the header value and injects new headers. Fastapi's underlying Starlette framework passes these characters through to the response, creating the vulnerability.

Another Fastapi-specific pattern involves dependency injection with header manipulation:

from fastapi import Depends

def get_user_agent(request: Request) -> str:
    return request.headers.get("user-agent", "unknown")

@app.get("/api/data")
async def get_data(user_agent: str = Depends(get_user_agent)):
    # Vulnerable: user-agent flows into response header
    return JSONResponse(
        content={"data": "sensitive"},
        headers={"X-User-Agent": user_agent}
    )

Fastapi's dependency injection system makes this pattern common, but it creates the same header injection risk when user-controlled headers flow back into responses.

Path parameter manipulation in Fastapi route definitions can also lead to header injection:

@app.get("/api/{path_param}/data")
async def get_data(path_param: str):
    # Vulnerable: path_param flows into response header
    return JSONResponse(
        content={"data": "sensitive"},
        headers={"X-Path-Param": path_param}
    )

Fastapi's automatic type conversion and validation don't sanitize header values, making this a persistent risk in production applications.

Fastapi-Specific Detection

Detecting header injection in Fastapi applications requires both static analysis and runtime scanning. middleBrick's Fastapi-specific scanner identifies these vulnerabilities through black-box testing of your API endpoints.

middleBrick automatically tests for header injection by sending requests with CRLF sequences in path parameters, query parameters, and headers. The scanner specifically targets Fastapi's response construction patterns, testing endpoints that:

  • Return JSON responses with custom headers
  • Use dependency injection for header values
  • Construct response headers from request data
  • Include user-controlled data in CORS headers
  • Generate location headers from path parameters

The scanner provides Fastapi-specific findings with severity levels based on the potential impact. For example, header injection in authentication endpoints receives higher severity than in informational endpoints.

Running middleBrick against your Fastapi application is straightforward:

middlebrick scan https://api.yourfastapi.com

The scanner tests all exposed endpoints, including those with Fastapi's automatic OpenAPI documentation. It identifies endpoints that construct headers from user input and provides specific remediation guidance.

For continuous monitoring, the middleBrick GitHub Action can scan your Fastapi API in CI/CD pipelines:

- name: middleBrick API Security Scan
  uses: middleBrick/middlebrick-action@v1
  with:
    api_url: https://staging.yourfastapi.com
    fail_below_score: 80

This integration catches header injection vulnerabilities before they reach production, failing builds when security scores drop below your threshold.

middleBrick's Fastapi-specific detection includes LLM/AI security scanning for endpoints that might serve AI/ML models, testing for system prompt leakage and prompt injection vulnerabilities that could be combined with header injection attacks.

Fastapi-Specific Remediation

Remediating header injection in Fastapi requires proper input validation and header sanitization. Fastapi provides several mechanisms to prevent these vulnerabilities.

The most effective approach is using Fastapi's built-in validation with Pydantic models:

from fastapi import FastAPI, Request, Header
from pydantic import BaseModel, constr
from fastapi.responses import JSONResponse

app = FastAPI()

class UserID(BaseModel):
    user_id: constr(min_length=1, max_length=100, strip_whitespace=True)
    
@app.get("/api/user/{user_id}")
async def get_user(request: Request, user_id: str):
    # Validate and sanitize user_id
    if "\r" in user_id or "\n" in user_id:
        raise HTTPException(status_code=400, detail="Invalid user ID")
    
    # Safe: user_id is validated before use
    return JSONResponse(
        content={"message": "User data"},
        headers={"X-User-ID": user_id}
    )

This pattern validates that the user_id contains no newline characters before using it in headers. Fastapi's Pydantic integration makes this validation straightforward.

For dependency injection scenarios, sanitize header values before use:

from fastapi import Depends

def get_user_agent(request: Request) -> str:
    user_agent = request.headers.get("user-agent", "unknown")
    # Sanitize: remove newline characters
    if "\r" in user_agent or "\n" in user_agent:
        raise HTTPException(status_code=400, detail="Invalid user agent")
    return user_agent

@app.get("/api/data")
async def get_data(user_agent: str = Depends(get_user_agent)):
    return JSONResponse(
        content={"data": "sensitive"},
        headers={"X-User-Agent": user_agent}
    )

Fastapi's exception handling ensures that invalid requests are rejected before header construction occurs.

For path parameters, use Fastapi's type validation with custom sanitization:

from fastapi import HTTPException

@app.get("/api/{path_param}/data")
async def get_data(path_param: str):
    # Sanitize path parameter
    if "\r" in path_param or "\n" in path_param:
        raise HTTPException(status_code=400, detail="Invalid path parameter")
    
    return JSONResponse(
        content={"data": "sensitive"},
        headers={"X-Path-Param": path_param}
    )

Fastapi's middleware can also sanitize all outgoing headers:

from fastapi import Request, Response
from fastapi.middleware.base import BaseHTTPMiddleware

class HeaderSanitizationMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        response = await call_next(request)
        
        # Sanitize all headers
        for header_name in response.headers.keys():
            if "\r" in header_name or "\n" in header_name:
                del response.headers[header_name]
        
        return response

app.add_middleware(HeaderSanitizationMiddleware)

This middleware provides defense-in-depth by sanitizing headers at the response level, catching any header injection that bypasses earlier validation.

Frequently Asked Questions

Why doesn't Fastapi automatically sanitize header values?
Fastapi follows the principle of least surprise, treating header values as raw data. Automatic sanitization could break legitimate use cases where newline characters are valid (such as multi-line headers). Fastapi relies on developers to validate input based on their specific application requirements.
Can header injection be combined with other Fastapi vulnerabilities?
Yes, header injection often combines with authentication bypass vulnerabilities. An attacker could inject authentication headers to escalate privileges, or combine it with path traversal to access unauthorized resources. This is why middleBrick scans for multiple vulnerability types simultaneously.