Auth Bypass in Fastapi with Basic Auth
Auth Bypass in Fastapi with Basic Auth — how this specific combination creates or exposes the vulnerability
Basic Authentication in FastAPI transmits credentials as a base64-encoded string without encryption, making it vulnerable to interception if not protected by TLS. When TLS is not enforced or is misconfigured, credentials can be captured with trivial network sniffing, leading to an auth bypass scenario where an attacker gains access without valid credentials.
Additionally, FastAPI applications that improperly validate credentials or rely solely on the presence of an Authorization header can be vulnerable to bypass techniques. For example, if the dependency that extracts and verifies Basic Auth credentials does not consistently enforce scheme validation and credential checks, an attacker may supply malformed or missing credentials and still pass through to protected routes. This can occur when route dependencies are conditionally applied or when developer code treats a missing header as equivalent to a valid but empty authentication set.
Another vector involves endpoints that mix authentication schemes or fall back to unauthenticated access during partial configuration failures. If an application defines multiple security schemes and fails to explicitly require the correct one for each route, FastAPI may default to a less restrictive or no-security dependency, effectively bypassing Basic Auth protections. Misconfigured global dependencies that skip authentication for certain paths, or that use SecurityScopes without precise scope validation, can further weaken the expected access control, enabling unauthenticated or unauthorized access to sensitive endpoints.
Middleware or reverse proxy layers in front of FastAPI can also introduce bypass risks if they strip or rewrite Authorization headers incorrectly, or if they permit unauthenticated requests to reach the application when they should be challenged. Without runtime checks that correlate the OpenAPI spec definition of security requirements with actual behavior, such configuration mismatches remain undetected, allowing the attack surface to expand beyond intended authentication boundaries.
Basic Auth-Specific Remediation in Fastapi — concrete code fixes
To securely implement Basic Authentication in FastAPI, always enforce TLS in production to protect credentials in transit. Use FastAPI’s built-in security utilities with explicit HTTP Basic schemes and validate credentials on every request. Below is a secure example using HTTPBasic and a verified dependency that ensures only valid credentials grant access.
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import HTTPBasic, HTTPBasicCredentials
import secrets
app = FastAPI()
security = HTTPBasic()
# In production, store and verify credentials securely (e.g., hashed and compared with constant-time checks)
VALID_USER = "admin"
VALID_PASS = "s3cur3P@ss!" # placeholder; use secrets and hashing in real use
def verify_basic_auth(credentials: HTTPBasicCredentials = Depends(security)):
if credentials.username != VALID_USER:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid credentials",
headers={"WWW-Authenticate": "Basic"},
)
if not secrets.compare_digest(credentials.password, VALID_PASS):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid credentials",
headers={"WWW-Authenticate": "Basic"},
)
return credentials.username
@app.get("/secure-data")
def read_secure(username: str = Depends(verify_basic_auth)):
return {"message": f"Hello, {username}. This is protected data."}
@app.get("/open-endpoint")
def read_public():
return {"note": "This endpoint does not require authentication."}
Ensure your OpenAPI spec reflects the security requirement so scanners and downstream tools can correlate expected authentication with runtime behavior. You can annotate routes explicitly or use global security schemes:
from fastapi import FastAPI, Security
from fastapi.security import HTTPBasic
app = FastAPI()
security_scheme = HTTPBasic()
app.add_middleware(
# Avoid relying on middleware to enforce auth; prefer dependency injection
)
# Example security scheme in the OpenAPI spec
def get_openapi():
return {
"openapi": "3.0.3",
"info": {"title": "API", "version": "1.0.0"},
"paths": {
"/secure-data": {
"get": {
"responses": {"200": {"description": "OK"}},
"security": [{"basicAuth": []}]
}
}
},
"components": {
"securitySchemes": {
"basicAuth": {
"type": "http",
"scheme": "basic"
}
}
}
}
Remediation best practices include:
- Never accept requests without validating credentials, even if a header is missing; treat missing auth as unauthorized.
- Do not mix authentication schemes on the same route without explicit scoping; require the correct security scheme for protected paths.
- Use constant-time comparison for passwords to mitigate timing attacks.
- Correlated spec-defined security requirements with runtime dependencies to detect mismatches that enable bypass; tools that support OpenAPI/Swagger spec analysis with full $ref resolution can highlight inconsistencies between declared and enforced authentication.
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 |