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 ID | Name | Severity |
|---|---|---|
| CWE-287 | Improper Authentication | CRITICAL |
| CWE-306 | Missing Authentication for Critical Function | CRITICAL |
| CWE-307 | Brute Force | HIGH |
| CWE-308 | Single-Factor Authentication | MEDIUM |
| CWE-309 | Use of Password System for Primary Authentication | MEDIUM |
| CWE-347 | Improper Verification of Cryptographic Signature | HIGH |
| CWE-384 | Session Fixation | HIGH |
| CWE-521 | Weak Password Requirements | MEDIUM |
| CWE-613 | Insufficient Session Expiration | MEDIUM |
| CWE-640 | Weak Password Recovery | HIGH |