Broken Authentication in Fastapi with Basic Auth
Broken Authentication in Fastapi with Basic Auth — how this specific combination creates or exposes the vulnerability
HTTP Basic Authentication encodes a username and password with Base64 and transmits the token in the Authorization header on every request. In Fastapi, using Basic Auth without TLS means credentials are easily decoded in transit, and if logging or error handling inadvertently exposes the header, secrets can be leaked in application logs or error traces. Even with TLS, weak password policies, predictable accounts, or credential reuse make brute-force and credential-stuffing practical. Fastapi applications that rely solely on Basic Auth for authorization rather than using it as a transport for identity tokens are vulnerable to Broken Authentication because the protocol itself provides no protection against replay, lacks built-in mechanisms for secure token rotation, and does not enforce strong session management.
When combined with improper session handling, Basic Auth can amplify common API risks such as BOLA/IDOR and BFLA/Privilege Escalation. For example, if your Fastapi endpoints infer user context from the decoded Basic Auth identity but do not re-check authorization for each sensitive operation, horizontal or vertical privilege escalation becomes straightforward. MiddleBrick’s authentication checks validate whether Basic Auth is used strictly as a transport and whether subsequent authorization is enforced; this helps identify when credentials are accepted without sufficient verification of scope, audience, or freshness.
Another concern is unauthenticated LLM endpoint exposure: if a Fastapi service exposes an endpoint that returns model outputs without validating the caller, an attacker may probe for Basic Auth–protected routes and attempt to infer valid usernames via timing or error differences. MiddleBrick’s LLM Security checks include Unauthenticated LLM endpoint detection to surface such gaps. Additionally, if OpenAPI specs declare securitySchemes of type http with scheme basic but do not enforce HTTPS or require scoping, runtime findings may show mismatches between declared and actual protections, highlighting insecure configurations that facilitate credential theft or man-in-the-middle attacks.
Basic Auth-Specific Remediation in Fastapi — concrete code fixes
To reduce risk, treat HTTP Basic Auth as a credential transport and enforce strict supplementary controls in Fastapi. Always require HTTPS via middleware or deployment configuration so credentials are never sent in cleartext. Use strong password hashing on the server (e.g., Argon2 or bcrypt) and avoid storing plaintext secrets. Prefer token-based flows where Basic Auth is used only to initially obtain a short-lived access token, after which APIs rely on bearer tokens with proper scopes and revocation.
Implement robust authorization checks on every endpoint; do not infer permissions solely from the decoded identity. Enforce rate limiting to mitigate brute-force attempts, and ensure error messages do not disclose whether a username exists. Validate and scope tokens to the minimum required permissions, and rotate credentials regularly. Combine these practices with continuous scanning to detect misconfigurations; the Pro plan’s continuous monitoring can alert you if authentication patterns drift outside acceptable baselines.
Below are two Fastapi examples: an insecure pattern and a remediated pattern.
Insecure Fastapi Basic Auth example
from fastapi import Depends, Fastapi, Header, HTTPException, status
from base64 import b64decode
app = Fastapi()
# WARNING: This example is insecure and for illustration only
SECRET_USER = "admin"
SECRET_PASS = "plaintext123" # hardcoded, weak secret
def decode_basic(auth: str = Header(None)):
if not auth or not auth.startswith("Basic "):
return None
token = auth.split(" ")[1]
decoded = b64decode(token).decode("utf-8")
return decoded # returns user:pass
@app.get("/items")
def read_items(auth: str = Depends(decode_basic)):
if not auth or auth != f"{SECRET_USER}:{SECRET_PASS}":
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials")
return {"data": "public items"}
Issues: plaintext password in code, no HTTPS enforcement, no rate limiting, exact string comparison leaks timing, no scope or token mechanism.
Remediated Fastapi Basic Auth example
from fastapi import Depends, Fastapi, Header, HTTPException, status, Security from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from passlib.context import CryptContext from pydantic import BaseModel import secrets app = Fastapi() security_scheme = HTTPBearer() pwd_context = CryptContext(schemes=["argon2"], deprecated="auto") # Simulated user store with hashed passwords USERS = { "alice": pwd_context.hash("StrongPassword!23"), "bob": pwd_context.hash("AnotherStrong!45") } class TokenData(BaseModel): username: str scopes: list[str] def verify_password(plain: str, hashed: str) -> bool: return pwd_context.verify(plain, hashed) def get_current_user(credentials: HTTPAuthorizationCredentials = Security(security_scheme)): token = credentials.credentials # In practice, validate a signed JWT or session token here # This simplified example demonstrates moving away from raw Basic Auth in requests raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Use bearer tokens") def authorize_user(user: TokenData, required_scope: str): if required_scope not in user.scopes: raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Insufficient scope") @app.get("/items") def read_items(auth: str = Header(None)): # Require HTTPS in production; reject cleartext Basic if auth and auth.startswith("Basic "): raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Basic Auth not allowed, use bearer tokens") # Example bearer validation would happen in get_current_user raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Authentication required")Remediation highlights: enforce HTTPS, avoid storing or comparing plaintext passwords, prefer bearer tokens with scopes, validate and scope every request, and use strong adaptive hashing for stored credentials.
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 |