One Character in an HTTP Header Just Bypassed Authentication on 325 Million Servers | by Tuğhan Belbek | Jun, 2026 | MediumSitemapOpen in appSign up<br>Sign in
Medium Logo
Get app<br>Write
Search
Sign up<br>Sign in
Press enter or click to view image in full size
One Character in an HTTP Header Just Bypassed Authentication on 325 Million Servers
Tuğhan Belbek
5 min read·<br>Just now
Listen
Share
325 million downloads per week. That’s how many times developers pull Starlette from PyPI. [1]<br>A single malformed character in an HTTP Host header now bypasses every path-based access control on every one of those servers. No password. No exploit kit. No social engineering. Just one character, injected into a header that every web request already carries.<br>The vulnerability is CVE-2026–48710, nicknamed “BadHost.” It was disclosed on May 22, 2026, after X41 D-Sec found it during a security audit of vLLM sponsored by OSTIF. [2] The patch, Starlette 1.0.1, shipped a day earlier. Most production servers still haven’t applied it.<br>What the bug actually does<br>Starlette reconstructs the full request URL by combining the HTTP Host header with the raw request path. The routing logic uses the raw path. But middleware and endpoints that check permissions often use request.url.path, which comes from that reconstructed URL.<br>Here’s the problem: Starlette validates the raw path and the reconstructed URL using different rules. A malformed Host header, something like evil.com/../admin, causes request.url.path to return /admin even though the actual request path was something harmless. [3]<br>Your middleware sees /admin, thinks the user is authorized for that path, and lets the request through. The router never even sees the attack because it's looking at a different path.<br>This is a well-understood class of attack called Host header injection. The tooling to exploit it has existed for years. X41 D-Sec’s advisory notes that exploitation requires “no novel capability from an attacker.” [2]<br>Why AI agents make this worse<br>The real damage isn’t a generic web app getting owned. It’s what those web apps are running.<br>Starlette sits underneath FastAPI, which sits underneath vLLM, LiteLLM, and the entire MCP server ecosystem. [4] These aren’t just APIs. They’re authenticated gateways that connect AI agents to databases, email accounts, calendars, and third-party services.<br>An MCP server is basically a bridge. Your AI agent says “check my email” and the MCP server authenticates to Gmail and returns the results. The agent itself never holds the Gmail password. The MCP server does.<br>Now imagine an attacker bypasses authentication on that MCP server with one header. They don’t just get into the API. They get the credentials the MCP server is holding for every service it connects to. [5]<br>Belgium’s Centre for Cybersecurity explicitly warned that threat actors will target this for “access to sensitive data and steal credentials, including credentials to third-party accounts which could be exploited in supply chain attacks.” [6]<br>The numbers don’t tell the whole story<br>The CVSS score is 7/10. Some researchers say that understates the risk. [7]<br>I agree. CVSS scores measure technical severity in a vacuum. They don’t account for deployment patterns. And the deployment pattern here is: a single dependency, buried three layers deep in the stack, running on millions of servers that most teams forgot they were using.<br>How many engineering teams know that vLLM pulls in Starlette? How many know that their LiteLLM proxy is built on FastAPI, which is built on Starlette? The transitive blast radius of this vulnerability is the entire Python AI infrastructure layer, and most of it is invisible to the people who would need to patch it.<br>Snyk has already published a proof-of-concept. [8] The exploit is public. The patch has been available for nine days. The gap between “patch exists” and “patch applied” is where most breaches happen.<br>What actually needs to change<br>This isn’t a Starlette problem. It’s a dependency visibility problem.<br>If your team can’t answer “what version of Starlette are we running in production?” within five minutes, you have a bigger issue than this specific CVE. The AI stack has become so layered, so abstracted, that the foundation is invisible until it breaks.<br>The fix is mechanical: upgrade to Starlette 1.0.1 or later. [3] The hard part is finding every place it’s running. If you have agents in production, model-serving proxies, eval dashboards, or anything that touches MCP, you need to audit your dependency tree today.<br>There’s also a free scanner at badhost.org that checks whether your server is exposed. [1] Use it. It takes thirty seconds.<br>The broader lesson is that the AI infrastructure stack is still infrastructure. It has the same failure modes as any other software supply chain. The difference is that the stakes are higher, because the credentials these systems hold aren’t just for your app. They’re for your users’ entire digital lives.<br>The patch is nine...