HIGH bola idorfastapibasic auth

Bola Idor in Fastapi with Basic Auth

Bola Idor in Fastapi with Basic Auth — how this specific combination creates or exposes the vulnerability

Broken Object Level Authorization (BOLA) occurs when an API exposes one user’s resource by allowing direct manipulation of object identifiers (IDs) without verifying that the requesting user owns that resource. In FastAPI with HTTP Basic Authentication, this risk is amplified when authentication confirms identity but authorization is not enforced on a per-request, per-object basis.

Consider a FastAPI endpoint that retrieves a user profile by ID:

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

app = FastAPI()
security = HTTPBasic()

# Dummy user store
USERS = {
    "alice": {"password": "alicepass", "user_id": "u_alice"},
    "bob": {"password": "bobpass", "user_id": "u_bob"}
}

def get_current_user(credentials: HTTPBasicCredentials = Depends(security)):
    user = USERS.get(credentials.username)
    if not user or user["password"] != credentials.password:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid credentials",
            headers={"WWW-Authenticate": "Basic"},
        )
    return user

@app.get("/users/{user_id}")
def read_user(user_id: str, user: dict = Depends(get_current_user)):
    # BOLA risk: no check that user["user_id"] matches the requested user_id
    return {"user_id": user_id, "data": "sensitive info"}

Here, Basic Auth verifies that the caller is a valid user (e.g., Alice), but it does not ensure that Alice can only access her own user_id. If Alice requests /users/u_bob, the endpoint returns Bob’s data because the route parameter is used directly without comparing it to the authenticated user’s ID. The authentication layer confirms identity, but the authorization layer is missing, enabling BOLA.

In black-box scanning, middleBrick would test this by submitting valid Basic Auth credentials for one user while manipulating the {user_id} path or query parameters to reference another user’s ID. The scan checks whether the response contains data belonging to the authenticated user. If data is returned, middleBrick flags a BOLA finding with severity and remediation guidance, referencing the OWASP API Top 10 A01:2023 broken object level authorization category.

Even when Basic Auth is used, developers often assume the transport-layer identity is sufficient. BOLA exploits the gap between authentication (who you are) and authorization (what you’re allowed to do). middleByte’s checks include verifying that object-level permissions align with the authenticated identity across all endpoints, including those using Basic Auth.

Basic Auth-Specific Remediation in Fastapi — concrete code fixes

To fix BOLA with Basic Auth in FastAPI, enforce that every request validates the mapping between the authenticated user and the resource identifier. This typically involves adding an explicit ownership or access check before returning data.

Below is a secure pattern where each user has a unique user_id, and endpoints compare the requested ID to the authenticated user’s ID:

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

app = FastAPI()
security = HTTPBasic()

USERS = {
    "alice": {"password": "alicepass", "user_id": "u_alice"},
    "bob": {"password": "bobpass", "user_id": "u_bob"}
}

def get_current_user(credentials: HTTPBasicCredentials = Depends(security)):
    user = USERS.get(credentials.username)
    if not user or user["password"] != credentials.password:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid credentials",
            headers={"WWW-Authenticate": "Basic"},
        )
    return user

@app.get("/users/{user_id}")
def read_user(
    user_id: str,
    user: dict = Depends(get_current_user)
):
    # BOLA mitigation: ensure the requested ID matches the authenticated user’s ID
    if user["user_id"] != user_id:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="You do not have permission to access this resource",
        )
    return {"user_id": user_id, "data": "secure info for " + user["username"]}

This pattern makes the authorization explicit: after authentication, the endpoint compares the path parameter user_id to the authenticated user’s stored ID. A mismatch results in a 403 Forbidden, preventing unauthorized access regardless of the validity of the Basic Auth credentials.

For endpoints involving indirect references (e.g., foreign keys or UUIDs), maintain an access control list or use a repository function that checks ownership before returning data:

def get_user_resource(user_id: str, current_user: dict):
    # Example: fetch resource and verify ownership
    resource = fetch_resource_from_db(user_id)
    if resource["owner_id"] != current_user["user_id"]:
        raise HTTPException(status_code=403, detail="Forbidden")
    return resource

middleBrick’s scans validate that such checks exist and are triggered for all object identifiers. In the Pro plan, continuous monitoring can alert you if a new endpoint lacks proper ownership verification, and the GitHub Action can fail CI/CD builds when a regression introduces a BOLA risk.

Related CWEs: bolaAuthorization

CWE IDNameSeverity
CWE-250Execution with Unnecessary Privileges HIGH
CWE-639Insecure Direct Object Reference CRITICAL
CWE-732Incorrect Permission Assignment HIGH

Frequently Asked Questions

Does using Basic Auth over HTTPS prevent BOLA?
No. Transport-layer encryption (HTTPS) protects credentials in transit, but it does not enforce object-level permissions. BOLA is about authorization, not confidentiality of authentication. You must still validate that the authenticated user is allowed to access the specific resource.
Can middleBrick test Basic Auth–protected endpoints for BOLA?
Yes. middleBrick supports submitting credentials for authenticated scans. You can provide Basic Auth credentials so the scanner can test endpoints behind authentication while still checking for BOLA and other authorization issues.