MEDIUM format stringfastapijwt tokens

Format String in Fastapi with Jwt Tokens

Format String in Fastapi with Jwt Tokens — how this specific combination creates or exposes the vulnerability

A format string vulnerability occurs when user-controlled input is passed directly into a formatted output function without proper sanitization. In FastAPI, this risk can intersect with JWT token handling when developer code uses unchecked request data to construct log entries, error messages, or debugging output that includes token values or claims. For example, if a route receives a username or a token identifier via query or body parameters and then uses Python’s percent-style or str.format syntax to build a message, an attacker can supply format specifiers such as %s, %x, or %n to read stack memory or cause unintended behavior. Because JWT tokens are often long strings containing sensitive metadata, exposing them through formatted output can leak information that assists further attacks.

Consider a FastAPI endpoint that logs authentication attempts by embedding the token directly into a format string:

from fastapi import FastAPI, Header

app = FastAPI()

@app.get("/items")
def read_items(authorization: str = Header(None)):
    message = "Auth token: %s" % authorization  # Risk if authorization is attacker-controlled
    print(message)
    return {"status": "ok"}

If an attacker sends authorization as %s %s %s, the application may leak memory contents or raise exceptions that reveal internal state. Similarly, using str.format with user input poses the same class of risk:

log_msg = "Token submitted: {}".format(user_token)

In both cases, the JWT token value or surrounding context can be manipulated through format specifiers, especially when the developer assumes the input is a simple opaque string. Because FastAPI applications often integrate with security middleware that handles JWT validation, accidental exposure through logging or error formatting creates an information disclosure vector. Attackers can chain this with other weaknesses, such as missing rate limiting or insecure error handling, to perform reconnaissance or refine injection attempts. The vulnerability is not in JWT parsing itself, but in how token-related data is handled post-validation.

Jwt Tokens-Specific Remediation in Fastapi — concrete code fixes

To mitigate format string risks when working with JWT tokens in FastAPI, ensure that any user-influenced data used in string construction is treated as plain values, not format templates. Prefer explicit concatenation or secure logging utilities that do not interpret format specifiers. Below are concrete, safe patterns for handling JWT tokens in request headers and responses.

Remediation example 1: Safe logging with f-strings or explicit concatenation

Instead of using percent or str.format interpolation, use f-strings where the token is inserted as a value, not as a format directive:

from fastapi import FastAPI, Header

app = FastAPI()

@app.get("/items")
def read_items(authorization: str = Header(None)):
    # Safe: token is a value, not a format string
    message = f"Auth token: {authorization}"
    print(message)
    return {"status": "ok"}

Remediation example 2: Structured logging with dictionaries

Use structured logging libraries (e.g., Python’s built-in logging with dict-like messages or a dedicated logger) to avoid interpreting input as format directives:

import logging
from fastapi import FastAPI, Header

app = FastAPI()
logger = logging.getLogger("security")

@app.get("/items")
def read_items(authorization: str = Header(None)):
    logger.info("Auth token received", extra={"token": authorization})
    return {"status": "ok"}

Remediation example 3: Input validation and length limits

Validate JWT tokens to ensure they conform to expected patterns (e.g., base64url segments separated by dots) and enforce length limits to reduce the impact of accidental exposure:

from fastapi import FastAPI, Header, HTTPException
import re

app = FastAPI()

JWT_PATTERN = re.compile(r'^[A-Za-z0-9._\-]+\.[A-Za-z0-9._\-]+\.[A-Za-z0-9._\-]+$')

@app.get("/items")
def read_items(authorization: str = Header(None)):
    if not authorization or not JWT_PATTERN.match(authorization):
        raise HTTPException(status_code=400, detail="Invalid token format")
    # Safe usage after validation
    return {"token_valid": True}

Remediation example 4: Avoid embedding tokens in error messages

Ensure that exception handlers do not include raw token values in responses or logs. Use generic error messages and log token metadata separately with strict access controls:

from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse

app = FastAPI()

@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
    # Do not include token or user input in public response
    return JSONResponse(
        status_code=500,
        content={"error": "Internal server error"}
    )

Frequently Asked Questions

Can a format string vulnerability in FastAPI lead to JWT token theft?
It can expose JWT token values if developer code uses user-controlled input in formatted output (e.g., logging or error messages). The token itself is not stolen by the format string bug alone, but leaked content can aid further attacks.
Does middleBrick detect format string issues related to JWT tokens in FastAPI scans?
middleBrick tests input validation, injection, and data exposure checks that can surface unsafe handling of token-like inputs. Findings include guidance on secure logging and validation practices for JWT usage.