Starlette request smuggling sounds like a legacy web-server problem, but it's turning up in modern async Python stacks running FastAPI and Uvicorn behind reverse proxies. In March 2024, a routine dependency audit at a mid-size fintech surfaced something unsettling: a reverse proxy in front of their FastAPI checkout service parsed a chunked request body differently than the Uvicorn server sitting behind it. That mismatch is enough to smuggle a second, hidden request into a shared connection — a classic HTTP desync attack, this time playing out inside a modern async Python stack. FastAPI now backs infrastructure processing billions of requests a month, and Starlette, its routing and request layer, inherits whatever the underlying ASGI server decides a request boundary actually is. This post breaks down where that risk lives, why it slips past code review, and what Safeguard does to catch it before attackers do.
What is Starlette request smuggling, and why does it matter for FastAPI?
Starlette request smuggling happens when the Starlette/Uvicorn stack and an upstream component — a load balancer, CDN, or API gateway — disagree about where one HTTP request ends and the next one begins, letting an attacker's crafted request "smuggle" a second, attacker-controlled request past whatever access controls sit in front of it. The classic variants are CL.TE (the front end trusts Content-Length, the back end trusts Transfer-Encoding), TE.CL (the reverse), and TE.TE (both trust Transfer-Encoding, but one can be tricked into ignoring it via obfuscation). This is sometimes described more broadly as ASGI request smuggling, because the ambiguity sits at the boundary where raw HTTP bytes get translated into an ASGI scope dictionary — the interface FastAPI, Starlette, and every other ASGI framework build on top of.
It matters because of scale. Starlette shipped in 2018 as Tom Christie's lightweight ASGI toolkit, and FastAPI, built directly on top of it, has since become one of the most-adopted Python web frameworks in production — north of 80,000 GitHub stars and well over 100 million PyPI downloads a month by 2025. A framing-layer bug in this stack doesn't affect a handful of hobby projects; it affects payment APIs, internal auth gateways, and public-facing services that sit behind exactly the kind of multi-hop proxy chains where smuggling thrives.
How does a request smuggling flaw slip past normal code review and testing?
It slips past because the vulnerability lives in the disagreement between two components' HTTP parsers, not in your application logic, so unit tests, route-handler code review, and even most functional QA never exercise it. Your FastAPI endpoint code looks fine — it never sees the malformed second request, because from its point of view no such request arrived. The smuggled request either lands on the next connection reuse, gets attributed to a different, unsuspecting client, or bypasses an authentication check enforced only at the proxy layer.
This is exactly the pattern security researcher James Kettle popularized in his 2019 "HTTP Desync Attacks" research at PortSwigger, which found request smuggling issues across major production sites and generated publicly documented bounty payouts reported to exceed $70,000 within months of disclosure. The lesson that transferred to the async Python world is the same one: smuggling bugs are found by testing the deployed topology — proxy plus app server plus framework — not by reviewing source code in isolation. If your test suite talks directly to Uvicorn on localhost, it will never reproduce a bug that only exists when nginx or an ALB is in front of it.
Is this a real uvicorn security vulnerability, or just theoretical?
It's documented, not theoretical: Uvicorn ships two interchangeable HTTP parsing backends, h11 and httptools, and the two have not always agreed on how to handle malformed Transfer-Encoding values, duplicate Content-Length headers, or non-standard whitespace in header fields. That divergence is the raw material smuggling attacks are built from. The h11 library — a pure-Python, RFC 7230-focused parser — tightened its handling of ambiguous framing headers in its 0.14.0 release in February 2022, explicitly closing off several header-parsing edge cases that could otherwise be abused to disagree with a stricter or looser peer. httptools, by contrast, is a thin Cython wrapper around a C parser descended from Node.js's http-parser lineage, and it inherits whatever leniency that parser applies to malformed input.
Running two backends with different tolerance for malformed HTTP is precisely the kind of environment where a genuine uvicorn security vulnerability can hide: an app that behaves safely with h11 in staging can behave differently in production if it's deployed with httptools for performance, or vice versa. There isn't one headline CVE with a catchy name attached to this class of issue — which is part of why it's underappreciated relative to how much production traffic runs through this exact combination of components.
Why does FastAPI's HTTP parsing risk trace back to which server sits underneath it?
Because FastAPI and Starlette never touch raw HTTP bytes at all — they receive an already-parsed ASGI scope — so the entire framing-ambiguity attack surface is inherited from whichever server runs underneath: Uvicorn, Hypercorn, or Daphne. This is the core of the FastAPI HTTP parsing risk: your framework choice determines almost nothing about smuggling resistance, but your server and deployment topology determine almost everything.
Consider a concrete example. An attacker sends a request with both Content-Length: 6 and Transfer-Encoding: chunked set. RFC 7230 says Transfer-Encoding should take precedence when both are present, but not every proxy enforces that rule the same way. If the front-end load balancer honors Content-Length and forwards only six bytes as "the request," while Uvicorn's h11 parser honors Transfer-Encoding and keeps reading the chunked body, the tail end of that first request gets reinterpreted as the beginning of the next one on the same kept-alive connection. In a common production layout — nginx or an AWS ALB terminating TLS and forwarding to a pool of Gunicorn-managed Uvicorn workers — that single header disagreement is enough to desync the connection.
What did CVE-2024-24762 reveal about parsing risk in the Starlette stack?
CVE-2024-24762, patched in Starlette 0.36.2 in January 2024, showed that Starlette's own header and body parsing — not just server-level framing — could be weaponized, even outside classic smuggling. A maliciously crafted Content-Type header on a multipart form request could trigger catastrophic backtracking in the regular expression Starlette used to parse the multipart boundary, pinning a worker's event loop on a single request and stalling every other coroutine sharing it.
It's a denial-of-service bug rather than a smuggling one, but it's a useful sibling case: it confirms, with a concrete CVE ID and a concrete patch date, that the parsing layer underneath FastAPI has real, exploitable soft spots — and that those spots aren't limited to the transport-framing questions that classic CL.TE/TE.CL smuggling depends on. Any team treating "we use FastAPI" as a proxy for "our HTTP parsing is safe" should read CVE-2024-24762 as a reminder that the parsing surface is broader than just Content-Length and Transfer-Encoding, and that it has already produced a shipped, numbered vulnerability once.
How Safeguard Helps
Request smuggling in an ASGI stack is fundamentally a supply-chain visibility problem before it's an application security problem: you need to know exactly which HTTP parser (h11 or httptools), which Uvicorn version, and which Starlette version is running behind every proxy in your fleet, and whether any of those combinations have drifted out of sync with what your edge infrastructure expects. Safeguard maps that dependency graph automatically across services, flagging Starlette, Uvicorn, h11, and httptools versions the moment they're pulled into a build, and correlating them against known parsing-related advisories like CVE-2024-24762 as they're disclosed.
Because the risk shows up at the intersection of components rather than inside a single package, Safeguard also tracks deployment topology metadata — which services sit behind which proxies or load balancers — so teams can see where mismatched HTTP parsing assumptions are most likely to produce a real desync, not just a theoretical one. Policy gates can block a deploy that introduces an outdated or unpatched parsing library before it reaches production, and continuous monitoring keeps watching after release, since a new CVE against h11, httptools, or Starlette can turn a previously safe deployment into an exposed one overnight. For teams that have standardized on FastAPI for its speed and developer experience, that combination of dependency-graph visibility and topology-aware risk correlation is what turns "we hope our proxy and our ASGI server agree" into something you can actually verify.