Missing Tls in Fastapi with Jwt Tokens
Missing Tls in Fastapi with Jwt Tokens — how this specific combination creates or exposes the vulnerability
Transport Layer Security (TLS) protects data in transit between clients and FastAPI applications. When TLS is missing or misconfigured, any communication can be observed or altered by network intermediaries. This becomes especially critical when the API uses JWT tokens for authentication, because tokens are bearer credentials that grant access to protected endpoints.
In a FastAPI service that relies on JWT tokens, missing TLS exposes tokens at multiple points:
- Login or token issuance endpoints that return an access token in the response body or an Authorization header.
- Subsequent requests that include the JWT in the Authorization: Bearer header.
- Token refresh flows where refresh tokens or new access tokens are transmitted.
Without encryption, tokens can be captured via passive network monitoring, compromised switches, or malicious Wi‑Fi access points. Even if the token itself is cryptographically signed, interception allows an attacker to reuse it (replay) until expiration. This violates the confidentiality guarantee expected when using bearer tokens and can lead to unauthorized access to user data or administrative functions.
The risk is compounded when token metadata (scopes, roles, sub) is not considered sensitive by operators who assume signature integrity alone is sufficient. In practice, many organizations treat bearer tokens like passwords and require transmission only over encrypted channels. A FastAPI application that skips TLS may pass security reviews if scans rely only on localhost or internal networks, but exposes credentials once deployed to public endpoints.
middleBrick scans the unauthenticated attack surface and flags Missing TLS as a high-severity finding, noting that JWT tokens are transmitted without encryption and providing remediation guidance tied to the API’s observed behavior.
Jwt Tokens-Specific Remediation in Fastapi — concrete code fixes
To remediate Missing TLS in FastAPI when using JWT tokens, enforce HTTPS for all routes and ensure tokens are only transmitted over encrypted connections. Below are concrete, working examples that combine secure TLS enforcement with JWT handling.
Enforce HTTPS in FastAPI
Configure your production server (e.g., Uvicorn with SSL) and optionally redirect HTTP to HTTPS. This example shows a secure startup configuration and middleware that upgrades HTTP requests.
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import RedirectResponse
import ssl
app = FastAPI(title="Secure API with JWT")
@app.middleware("http")
async def enforce_https(request: Request, call_next):
if not request.url.scheme == "https":
return RedirectResponse(url=str(request.url.replace(scheme="https")), status_code=301)
response = await call_next(request)
return response
@app.get("/healthz")
async def healthz():
return {"status": "ok"}
if __name__ == "__main__":
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(certfile="fullchain.pem", keyfile="privkey.pem")
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=443, ssl_context=context)
Secure JWT Handling with HTTPS-Only Cookies (Alternative)
If you choose to use cookies rather than Authorization headers, set the Secure and HttpOnly flags and enforce SameSite=None for cross-site contexts served over HTTPS.
from fastapi import FastAPI, Response
from fastapi.security import HTTPOnlyCookieBearer
import jwt
app = FastAPI()
bearer_scheme = HTTPOnlyCookieBearer(tokenUrl="/token")
@app.post("/token")
async def login(response: Response):
payload = {"sub": "user-123", "scope": "read write"}
token = jwt.encode(payload, "super-secret-key", algorithm="HS256")
response.set_cookie(
key="access_token",
value=token,
httponly=True,
secure=True,
samesite="none",
max_age=3600
)
return {"message": "token set in secure cookie"}
JWT Validation over HTTPS
With TLS enforced, validate tokens on each request and ensure algorithms and keys are explicitly specified to prevent downgrade attacks.
from fastapi import FastAPI, Depends, HTTPException, Security
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
import jwt
app = FastAPI()
security = HTTPBearer()
SECRET_KEY = "super-secret-key"
ALGORITHM = "HS256"
def get_current_user(credentials: HTTPAuthorizationCredentials = Security(security)):
token = credentials.credentials
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
return payload
except jwt.ExpiredSignatureError:
raise HTTPException(status_code=401, detail="Token expired")
except jwt.InvalidTokenError:
raise HTTPException(status_code=401, detail="Invalid token")
@app.get("/protected")
async def protected_route(user: dict = Depends(get_current_user)):
return {"message": "ok", "user": user["sub"]}
Operational Practices
- Always terminate TLS at the edge (load balancer or reverse proxy) and ensure backend communication is also encrypted when applicable.
- Use strong algorithms (e.g., RS256 with asymmetric keys) and rotate keys according to your policy.
- Set short expiration times for access tokens and use refresh tokens over secure, HttpOnly cookies when needed.
- Include HTTPS enforcement in CI/CD checks so that builds fail if runtime scans (e.g., via middleBrick) detect tokens transmitted without encryption.
Related CWEs: encryption
| CWE ID | Name | Severity |
|---|---|---|
| CWE-319 | Cleartext Transmission of Sensitive Information | HIGH |
| CWE-295 | Improper Certificate Validation | HIGH |
| CWE-326 | Inadequate Encryption Strength | HIGH |
| CWE-327 | Use of a Broken or Risky Cryptographic Algorithm | HIGH |
| CWE-328 | Use of Weak Hash | HIGH |
| CWE-330 | Use of Insufficiently Random Values | HIGH |
| CWE-338 | Use of Cryptographically Weak PRNG | MEDIUM |
| CWE-693 | Protection Mechanism Failure | MEDIUM |
| CWE-757 | Selection of Less-Secure Algorithm During Negotiation | HIGH |
| CWE-261 | Weak Encoding for Password | HIGH |