HIGH broken authenticationfastapijwt tokens

Broken Authentication in Fastapi with Jwt Tokens

Broken Authentication in Fastapi with Jwt Tokens — how this specific combination creates or exposes the vulnerability

Broken Authentication in FastAPI with JWT tokens typically arises when token validation, encoding, or session handling is implemented inconsistently, enabling attackers to bypass authentication. Common patterns that lead to vulnerabilities include missing or weak signature verification, accepting unsigned tokens (alg=none), not validating the issuer (iss) or audience (aud), and storing sensitive data in the token payload without encryption. In FastAPI, if the application decodes tokens without enforcing algorithm constraints, an attacker can supply a token with alg=none and trick the server into trusting an unsigned payload.

Another frequent issue is improper token revocation and weak token expiration handling. For example, issuing access tokens with long lifetimes without refresh token rotation increases the window for token replay. Inadequate HTTPS enforcement and insecure transmission of tokens (e.g., via URL query parameters) can also lead to token leakage. Attack vectors aligned to this pattern include weak secret keys, predictable jti (JWT ID) values, and missing checks for token binding, enabling account takeover or privilege escalation. These weaknesses map to OWASP API Top 10:2023 — Broken Authentication and can be identified during a black-box scan that compares runtime behavior against expected validation rules and spec-defined security controls.

Jwt Tokens-Specific Remediation in Fastapi — concrete code fixes

Remediation centers on strict token validation, secure defaults, and defense-in-depth. Always enforce algorithm validation, validate standard claims, use HTTPS, and keep token lifetimes short with secure refresh mechanisms. Below are concrete, working code examples for secure JWT handling in FastAPI.

from datetime import datetime, timedelta, timezone
from typing import Optional

from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from jose import JWTError, jwt

SECRET_KEY = "your-very-strong-secret-that-is-at-least-32-chars"  # keep in env/secrets
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 15  # short-lived access tokens

app = FastAPI()
security = HTTPBearer()

def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
    to_encode = data.copy()
    expire = datetime.now(timezone.utc) + (expires_delta or timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES))
    to_encode.update({"exp": expire, "iat": datetime.now(timezone.utc), "jti": str(uuid4())})
    return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)

def decode_token(token: str):
    # Enforce algorithm and validate standard claims
    try:
        payload = jwt.decode(
            token,
            SECRET_KEY,
            algorithms=[ALGORITHM],
            options={"require": ["exp", "iat", "jti", "sub"]},
        )
        return payload
    except JWTError as e:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid authentication credentials",
            headers={"WWW-Authenticate": "Bearer"},
        ) from e

@app.post("/login")
def login():
    # Example: issue token with minimal, non-sensitive claims
    access_token = create_access_token(data={"sub": "user-uuid", "scopes": ["read", "write"]})
    return {"access_token": access_token, "token_type": "bearer"}

@app.get("/protected")
def read_protected(credentials: HTTPAuthorizationCredentials = Depends(security)):
    payload = decode_token(credentials.credentials)
    return {"user": payload.get("sub"), "scopes": payload.get("scopes")}

Key remediation practices reflected in the code:

  • Enforce a strong algorithm (HS256/RS256) and never accept alg=none; explicitly pass algorithms=[ALGORITHM] to decode.
  • Validate exp, iat, jti, and sub; use require options to reject malformed tokens.
  • Keep access token lifetimes short (minutes) and implement refresh tokens with rotation and revocation support.
  • Store secrets in environment variables or a secrets manager; do not hardcode keys in source.
  • Use HTTPS in production and transmit tokens only via the Authorization header.
  • Consider issuer (iss) and audience (aud) validation when tokens are issued by an identity provider.

These controls align with the checks run by tools like middleBrick, which tests unauthenticated attack surfaces and flags missing validation, weak algorithms, and excessive agency patterns. The Pro plan can integrate these checks into CI/CD pipelines to fail builds if security scores drop below your threshold, while the Web Dashboard helps you track API security scores over time.

Related CWEs: authentication

CWE IDNameSeverity
CWE-287Improper Authentication CRITICAL
CWE-306Missing Authentication for Critical Function CRITICAL
CWE-307Brute Force HIGH
CWE-308Single-Factor Authentication MEDIUM
CWE-309Use of Password System for Primary Authentication MEDIUM
CWE-347Improper Verification of Cryptographic Signature HIGH
CWE-384Session Fixation HIGH
CWE-521Weak Password Requirements MEDIUM
CWE-613Insufficient Session Expiration MEDIUM
CWE-640Weak Password Recovery HIGH

Frequently Asked Questions

How does middleBrick detect missing JWT algorithm enforcement in FastAPI endpoints?
middleBrick runs black-box checks that include sending tokens with alg=none and verifying whether the server accepts unsigned payloads, in addition to inspecting OpenAPI/Swagger specs for required validation constraints and comparing them to runtime behavior.
Can the middleBrick CLI produce JSON output for automated handling of JWT-related findings?
Yes; use middlebrick scan --format json to get structured results, which you can parse in scripts or integrate into CI/CD workflows, for example via the GitHub Action to fail builds when risk scores exceed your defined thresholds.