HIGH distributed denial of servicefastapibasic auth

Distributed Denial Of Service in Fastapi with Basic Auth

Distributed Denial Of Service in Fastapi with Basic Auth — how this specific combination creates or exposes the vulnerability

When a Fastapi service relies solely on HTTP Basic Authentication and is exposed to the public internet, the authentication mechanism itself can become an amplification vector for Distributed Denial Of Service (DDoS). Basic Auth transmits credentials in an easily reversible format (base64) and typically requires the server to validate credentials on every request, often involving a backend identity provider or directory lookup. If the endpoint lacks sufficient rate limiting or if the authentication path is computationally heavier than expected (for example, validating credentials against a slow directory or performing additional role checks on each request), an attacker can issue many concurrent unauthenticated or low-privilege requests to consume server resources.

In a black-box scan, middleBrick tests the unauthenticated attack surface and checks for missing Rate Limiting alongside Authentication. Without rate controls, an unauthenticated caller can repeatedly trigger the Basic Auth verification logic, tying up worker processes or threads. In Fastapi, if the authentication logic is not optimized or if the dependency is invoked on every route without short-circuiting for public endpoints, this can lead to high CPU usage or thread exhaustion under load. The scan also flags endpoints where authentication is required but enforcement is inconsistent (e.g., some routes protected, others not), which can allow attackers to focus effort on the less-protected paths.

Because middleBrick runs 12 security checks in parallel, the Authentication and Rate Limiting checks work together to surface this risk: weak or missing rate limits combined with Basic Auth validation can result in a low score for Availability. The scan does not assume an internal architecture, but the findings highlight that an attacker can generate enough requests to exhaust connection pools or trigger expensive credential validation, contributing to denial of service for legitimate users.

Basic Auth-Specific Remediation in Fastapi — concrete code fixes

To reduce DDoS risk when using Basic Auth in Fastapi, combine lightweight authentication with strict rate limiting and avoid expensive per-request work. Below are concrete, working examples that demonstrate a safer approach.

1. Basic Auth with fastapi.security.HTTPBasic and optimized validation

Use HTTPBasic for simplicity, but ensure credentials are validated efficiently (e.g., via a fast in-memory cache or a precomputed hash) and that expensive directory lookups are minimized. Do not perform heavy computation or multiple remote calls on every request.

from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import HTTPBasic, HTTPBasicCredentials
import secrets
import time

app = FastAPI()
security = HTTPBasic()

# Example: simple in-memory credential store (for demo only; use a secure backend in production)
VALID_USERNAME = "apiuser"
# Store a pre-hashed value; avoid storing plaintext passwords
VALID_PASSWORD_HASH = secrets.token_hex(32)  # Replace with a proper hash of your password

# Rate-limiting helper: track request timestamps per credentials
from collections import deque
request_log = deque()
RATE_LIMIT_WINDOW = 60  # seconds
MAX_REQUESTS_PER_WINDOW = 100

def is_rate_limited():
    now = time.time()
    # Remove outdated entries
    while request_log and request_log[0] <= now - RATE_LIMIT_WINDOW:
        request_log.popleft()
    if len(request_log) >= MAX_REQUESTS_PER_WINDOW:
        return True
    request_log.append(now)
    return False

def get_current_user(credentials: HTTPBasicCredentials = Depends(security)):
    if is_rate_limited():
        raise HTTPException(
            status_code=status.HTTP_429_TOO_MANY_REQUESTS,
            detail="Rate limit exceeded",
        )
    # Compare pre-hashed credentials efficiently; avoid heavy work here
    if credentials.username != VALID_USERNAME:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid credentials",
            headers={"WWW-Authenticate": "Basic"},
        )
    # Use a constant-time comparison for the password hash in real use
    if credentials.password != VALID_PASSWORD_HASH:  # Replace with proper hash check
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid credentials",
            headers={"WWW-Authenticate": "Basic"},
        )
    return credentials.username

@app.get("/items/")
def read_items(current_user: str = Depends(get_current_user)):
    return {"message": f"Hello, {current_user}"}

2. Apply rate limiting at the API gateway or router level

In production, offload per-request work by enforcing rate limits at the edge or via a dependency that is shared across routes. This prevents an unbounded number of authentication checks under load.

from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import HTTPBasic, HTTPBasicCredentials
from starlette.middleware.base import BaseHTTPMiddleware
import time

app = FastAPI()
security = HTTPBasic()

class RateLimitMiddleware(BaseHTTPMiddleware):
    def __init__(self, app, max_requests=100, window=60):
        super().__init__(app)
        self.max_requests = max_requests
        self.window = window
        self.requests = []

    async def dispatch(self, request, call_next):
        now = time.time()
        self.requests = [t for t in self.requests if t > now - self.window]
        if len(self.requests) >= self.max_requests:
            from starlette.responses import JSONResponse
            return JSONResponse({"detail": "Rate limit exceeded"}, status_code=429)
        self.requests.append(now)
        response = await call_next(request)
        return response

app.add_middleware(RateLimitMiddleware, max_requests=100, window=60)

# Then mount routes as usual; authentication dependency can be reused
@app.get("/public/")
def public_endpoint():
    return {"public": True}

3. Use dependency short-circuiting and avoid redundant checks

Ensure that authentication dependencies are not applied to endpoints that do not require them, and avoid re-validating credentials when a lightweight token or session can be used after initial validation.

Check Risk if omitted Recommendation
Rate Limiting High CPU or connection pool exhaustion under request floods Enforce per-identity or per-client limits at middleware or gateway
Credential validation efficiency Slow verification increases latency and resource usage Use fast lookups and avoid remote calls on each request
Scope minimization Unauthenticated paths exposed due to misconfigured dependencies Apply auth dependencies only where needed

Frequently Asked Questions

Does middleBrick fix DDoS issues found in Fastapi with Basic Auth?
middleBrick detects and reports security findings, including missing rate limiting and authentication risks; it does not fix, patch, or block issues. Use the remediation guidance to adjust rate limits and optimize authentication in your Fastapi app.
How can I validate that my remediation reduced the DDoS risk?
After applying fixes such as adding rate limiting and optimizing credential validation, rescan the endpoint with middleBrick. The scanner’s per-category breakdown (Authentication, Rate Limiting) and prioritized findings will show whether the risk indicators have improved.