Replay Attack in Fastapi with Basic Auth
Replay Attack in Fastapi with Basic Auth — how this specific combination creates or exposes the vulnerability
A replay attack occurs when an attacker intercepts a valid authentication request and retransmits it to gain unauthorized access. When Fastapi uses HTTP Basic Auth without additional protections, the risk is elevated because the credentials are transmitted in every request. Basic Auth encodes the username and password with Base64, which is easily reversible. If the communication lacks strong transport security or request-level safeguards, an attacker who captures an encoded token can replay it to impersonate a legitimate user.
In Fastapi, Basic Auth is commonly implemented using HTTPBasic and HTTPBasicCredentials. The framework validates credentials on each request but does not inherently bind the authentication to a unique, single-use context such as a nonce or timestamp. This means that if an attacker observes a valid Authorization header, they can reuse it within the credential’s validity window. For example, an intercepted header like Authorization: Basic dXNlcjpwYXNz can be replayed to access protected endpoints until the credentials are rotated or the session expires.
The vulnerability is compounded when requests are not idempotent or when sensitive operations rely solely on static credentials. Attackers may capture traffic on insecure channels or compromise intermediaries to extract the encoded credentials. Because Basic Auth does not incorporate cryptographic nonces or per-request signatures, there is no mechanism to detect duplication. In a Fastapi application, endpoints that perform critical actions such as changing passwords or initiating transfers become attractive targets if they lack additional anti-replay controls like one-time tokens or strict request signing.
middleBrick scans identify such risks under the Authentication and BOLA/IDOR checks, highlighting cases where static credentials are reused without additional context-binding. The scanner evaluates whether the API relies on unauthenticated or weakly authenticated flows and flags missing replay protections. Developers should treat Basic Auth as a transport-layer convenience and augment it with mechanisms that ensure each request is unique and tied to a broader security context.
Basic Auth-Specific Remediation in Fastapi — concrete code fixes
To mitigate replay attacks in Fastapi with Basic Auth, combine secure transport with request-level protections. Always enforce HTTPS to prevent credential interception and augment Basic Auth with anti-replay techniques such as timestamps, nonces, or signed tokens. Below are concrete code examples that demonstrate a hardened approach.
1. Enforce HTTPS and Validate Origin
Ensure all endpoints are served over TLS and reject requests that do not use secure connections. Use Fastapi middleware to enforce strict transport security.
from fastapi import Fastapi, Request, HTTPException
app = Fastapi()
@app.middleware("http")
async def enforce_https(request: Request, call_next):
if not request.url.scheme == "https":
raise HTTPException(status_code=403, detail="HTTPS required")
response = call_next(request)
return response
2. Add Per-Request Nonce and Timestamp Validation
Require clients to include a nonce and timestamp in headers, and validate them server-side to prevent reuse. Store recently seen nonces temporarily to detect duplicates.
from fastapi import Fastapi, Header, HTTPException
import time
app = Fastapi()
seen_nonces = set()
@app.post("/secure-action")
async def secure_action(
authorization: str = Header(...),
x_nonce: str = Header(...),
x_timestamp: str = Header(...)
):
# Validate timestamp freshness (e.g., within 5 minutes)
try:
ts = int(x_timestamp)
except ValueError:
raise HTTPException(status_code=400, detail="Invalid timestamp")
if abs(time.time() - ts) > 300:
raise HTTPException(status_code=400, detail="Stale request")
# Prevent replay by checking nonce uniqueness
if x_nonce in seen_nonces:
raise HTTPException(status_code=401, detail="Replay detected")
seen_nonces.add(x_nonce)
# Proceed with Basic Auth validation
# ...
return {"status": "ok"}
3. Use Signed Tokens Alongside Basic Auth
Issue short-lived, cryptographically signed tokens after initial Basic Auth verification. Require these tokens for subsequent requests to bind the session to a specific context.
from fastapi import Fastapi, Depends, HTTPException, Header
import jwt
import time
SECRET_KEY = "your-secret-key"
app = Fastapi()
def generate_token(username: str) -> str:
payload = {"sub": username, "iat": int(time.time()), "exp": int(time.time()) + 300}
return jwt.encode(payload, SECRET_KEY, algorithm="HS256")
@app.post("/login")
async def login(authorization: str = Header(...)):
# Validate Basic Auth credentials
# If valid, return a signed token
token = generate_token("username")
return {"token": token}
async def get_current_token(token: str = Header(...)):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
return payload["sub"]
except jwt.InvalidTokenError:
raise HTTPException(status_code=401, detail="Invalid token")
@app.post("/action")
async def action(username: str = Depends(get_current_token)):
# Proceed with username-bound logic
return {"user": username}
4. Rotate Credentials and Use Short Lifetimes
Minimize the window for replay by enforcing short credential lifetimes and rotating secrets regularly. Combine with automated alerts for repeated failed validations that may indicate replay attempts.
By layering these measures, Fastapi applications can retain the simplicity of Basic Auth while significantly reducing the risk of replay attacks. middleBrick’s continuous monitoring can help detect patterns indicative of replay behavior and ensure that remediation aligns with frameworks such as OWASP API Top 10 and PCI-DSS.