java-topology/whitepaper/outreach/fastapi.md

2.6 KiB
Raw Blame History

FastAPI — CWE-407 Disclosure Brief

2026-03-27 · Patch available — awaiting upstream merge

Finding

One O(n²) defect in FastAPI's dependency resolution system. The get_flat_dependant() function uses a list for the visited set when flattening dependency graphs, causing O(D) scans per node and O(D²) total resolution cost. Patch ready for upstream review.

The Defects

fastapi-0001 (PATCHED — HIGH): dependencies/utils.py:142

# visited: list
# Inside get_flat_dependant() dependency graph traversal:
def get_flat_dependant(dependant, visited=None):
    if visited is None:
        visited = []
    if dependant in visited:  # O(D) list scan per node
        return flat
    visited.append(dependant)
    ...

visited is a list. The in operator performs a linear scan over D already-visited dependants for every node in the dependency graph. With D total dependants: O(D²) total for full dependency tree flattening.

Complexity Proof

For D dependency nodes:

  • get_flat_dependant() visits D nodes
  • Each in visited check scans up to D entries
  • Total: O(D²)

At D=500: defective=125,000 comparisons, fixed=500 set lookups. Measured ratio: 500×.

Impact

All FastAPI applications — dependency injection is the core mechanism for request handling in FastAPI. Every request to an endpoint with dependencies calls the dependency resolution path. Applications with deep or complex dependency graphs (authentication, database sessions, shared services, nested dependencies) are most affected. FastAPI is one of the most widely used Python web frameworks.

The Fix

Replace list with set for visited:

# Before
def get_flat_dependant(dependant, visited=None):
    if visited is None:
        visited = []
    if dependant in visited:  # O(D) list scan
        return flat
    visited.append(dependant)

# After
# CWE-407 fix: set for O(1) membership instead of O(D) list scan.
def get_flat_dependant(dependant, visited=None):
    if visited is None:
        visited = set()
    if dependant in visited:  # O(1) set lookup
        return flat
    visited.add(dependant)

Patch

defects/fastapi/patch/fastapi-0001-dependencies-set-visited.patch

What We Ask

  1. Confirm receipt and assign a GitHub Security Advisory or issue reference.
  2. Validate the patch against your dependency injection test suite.
  3. Assess CVE eligibility — fires on every request to endpoints with complex dependency graphs.
  4. Coordinate a disclosure date — we are targeting 90 days from first contact.

Contact: see cover email. This brief is confidential until coordinated disclosure.