HIGH broken authenticationfastapi

Broken Authentication in Fastapi

How Broken Authentication Manifests in Fastapi

Broken authentication in Fastapi applications typically emerges through several specific implementation patterns that developers often overlook. The most common vulnerability occurs when developers rely on Fastapi's default behavior without implementing proper session management or token validation.

A critical weakness appears when using Fastapi's Depends() for authentication without proper scope validation. Consider this vulnerable pattern:

from fastapi import Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
from pydantic import BaseModel

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="auth/token")

async def get_current_user(token: str = Depends(oauth2_scheme)):
    credentials_exception = HTTPException(
        status_code=401,
        detail="Could not validate credentials",
        headers={"WWW-Authenticate": "Bearer"},
    )
    # Missing token validation logic!
    return User(id=1, username="default")

@app.get("/user/profile")
async def read_user_profile(current_user: User = Depends(get_current_user)):
    return current_user

This code accepts any token without validation, allowing attackers to bypass authentication entirely. The get_current_user function returns a valid User object regardless of the token's authenticity.

Another Fastapi-specific vulnerability involves improper dependency injection for authentication. When developers create authentication dependencies that don't properly propagate errors or validate permissions:

async def get_admin_user(token: str = Depends(oauth2_scheme)):
    user = await get_user_from_token(token)
    if user.role != "admin":
        raise HTTPException(status_code=401, detail="Admin access required")
    return user

@app.get("/admin/users")
async def read_admin_users(current_user: User = Depends(get_admin_user)):
    return await get_all_users()

The vulnerability here is that the dependency chain breaks if get_user_from_token fails silently, potentially returning None and causing downstream errors that could be exploited.

Fastapi's async nature introduces unique timing-based authentication bypass opportunities. When authentication checks are performed asynchronously without proper error handling:

async def get_current_user(token: str = Depends(oauth2_scheme)):
    user = await verify_token_async(token)
    if user is None:
        # Race condition: response might be sent before exception
        raise HTTPException(status_code=401)
    return user

Attackers can exploit the brief window between token verification failure and exception raising, especially under high load where Fastapi's event loop behavior becomes unpredictable.

Fastapi-Specific Detection

Detecting broken authentication in Fastapi applications requires understanding both the framework's architecture and common vulnerability patterns. middleBrick's black-box scanning approach is particularly effective for Fastapi APIs because it tests the actual runtime behavior without needing source code access.

The scanner identifies Fastapi-specific authentication weaknesses by examining endpoint responses to various authentication scenarios. For instance, it tests whether endpoints that should require authentication accept requests without tokens, or whether different authentication schemes are properly isolated.

middleBrick's authentication detection includes these Fastapi-relevant checks:

{
  "authentication_checks": [
    "Missing token validation on protected endpoints",
    "Bearer token bypass attempts",
    "OAuth2 flow implementation verification",
    "Dependency injection authentication chain validation",
    "Async authentication race condition testing"
  ]
}

The scanner sends crafted requests to Fastapi endpoints to verify authentication enforcement. It attempts to access protected routes without tokens, with invalid tokens, and with tokens that should have insufficient permissions. Fastapi's automatic OpenAPI generation helps middleBrick understand the expected authentication requirements for each endpoint.

For Fastapi applications using Pydantic models for user data, middleBrick specifically tests for property authorization vulnerabilities where authenticated users might access data belonging to other users through IDOR (Insecure Direct Object Reference) attacks:

@app.get("/users/{user_id}")
async def read_user(user_id: int, current_user: User = Depends(get_current_user)):
    user = await get_user_by_id(user_id)
    if user is None:
        raise HTTPException(status_code=404)
    return user

middleBrick detects if authenticated users can access any user ID by systematically testing sequential user IDs and analyzing response patterns.

The scanner also identifies Fastapi's default error responses that might leak information about authentication implementation. When Fastapi returns detailed error messages about missing or invalid tokens, attackers can use this information to craft more effective attacks.

Fastapi-Specific Remediation

Securing Fastapi authentication requires implementing proper token validation, scope checking, and error handling. The foundation is a robust authentication dependency that validates tokens before allowing access:

from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from jose import JWTError, jwt
from datetime import datetime

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="auth/token")

async def get_current_user(token: str = Depends(oauth2_scheme)):
    try:
        payload = jwt.decode(
            token,
            SECRET_KEY,
            algorithms=[ALGORITHM]
        )
        username: str = payload.get("sub")
        if username is None:
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="Invalid authentication credentials",
                headers={"WWW-Authenticate": "Bearer"},
            )
        user = get_user_from_database(username)
        if user is None:
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="Invalid authentication credentials",
                headers={"WWW-Authenticate": "Bearer"},
            )
        return user
    except JWTError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid authentication credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )

This implementation ensures tokens are cryptographically validated before any user data is accessed, preventing the bypass vulnerabilities common in Fastapi applications.

For role-based access control in Fastapi, implement scoped dependencies that properly validate permissions:

async def get_current_active_user(
    current_user: User = Depends(get_current_user)
):
    if current_user.disabled:
        raise HTTPException(status_code=400, detail="Inactive user")
    return current_user

async def get_current_active_superuser(
    current_active_user: User = Depends(get_current_active_user)
):
    if current_active_user.role != "superuser":
        raise HTTPException(status_code=400, detail="Not enough permissions")
    return current_active_user

This dependency chain ensures that each layer of authentication and authorization is properly validated before access is granted.

Fastapi's async capabilities require special attention to authentication timing. Use proper error handling and avoid race conditions:

@app.middleware("http")
async def auth_middleware(request: Request, call_next):
    # Ensure authentication is completed before processing request
    if "/public/" not in request.url.path:
        try:
            await verify_authenticated(request)
        except HTTPException as e:
            return JSONResponse(
                status_code=e.status_code,
                content={"detail": e.detail}
            )
    
    response = await call_next(request)
    return response

This middleware approach ensures authentication is enforced consistently across all endpoints, addressing Fastapi's default behavior of processing requests before authentication is complete.

Related CWEs: authentication

CWE IDNameSeverity
CWE-287Improper Authentication CRITICAL
CWE-306Missing Authentication for Critical Function CRITICAL
CWE-307Brute Force HIGH
CWE-308Single-Factor Authentication MEDIUM
CWE-309Use of Password System for Primary Authentication MEDIUM
CWE-347Improper Verification of Cryptographic Signature HIGH
CWE-384Session Fixation HIGH
CWE-521Weak Password Requirements MEDIUM
CWE-613Insufficient Session Expiration MEDIUM
CWE-640Weak Password Recovery HIGH

Frequently Asked Questions

How does Fastapi's dependency injection system affect authentication security?
Fastapi's dependency injection allows authentication to be modular and reusable, but it also creates risks if dependencies don't properly validate or propagate errors. Each dependency in the chain must validate its requirements, and failures should raise exceptions rather than returning None or default values. The dependency system makes it easy to accidentally create authentication bypasses by forgetting to validate at each layer.
Can middleBrick scan Fastapi applications that use custom authentication schemes?
Yes, middleBrick's black-box scanning approach tests the actual runtime behavior of Fastapi APIs regardless of the authentication implementation. It examines endpoint responses to various authentication scenarios, tests for missing token validation, and verifies that protected endpoints properly enforce authentication requirements. The scanner doesn't need to understand your custom scheme—it tests whether the scheme actually works as intended.