Hardly any organisation lists Starlette in its asset register. It is the ASGI framework under FastAPI, and it processes every HTTP request that reaches LiteLLM, vLLM or any of the many MCP servers written in Python. On 2 September a CVSS 6.5 flaw in that library, CVE-2026-48710, was added to CISA's KEV catalogue together with two SonicWall SMA bugs, a Sangoma phone system, Artifactory, Kestra and a second LiteLLM flaw (CVE-2026-59822). A 6.5 does not usually draw attention on the KEV catalogue, and the reason this one made the list has little to do with Starlette itself.
The researchers who found the flaw named it BadHost on badhost.org, and it has been public since OSTIF published the details on 26 May; Starlette 1.0.1, released before that date, fixes it. What changed over the summer is how it is being used. Wiz has watched it hit its honeypots and Microsoft assesses that a real intrusion came in that way, in both cases chained with a LiteLLM flaw that lets an attacker run code on the AI gateway without credentials. Once inside, the target is the set of model-provider credentials the gateway holds.
At Hard2bit the Starlette version has been a standing check in every AI agent review since June. The reason is plain: most teams cannot say which version of that library travels inside their containers.
What is exploitable, and since when
The Starlette project advisory describes the flaw in a few lines. Versions before 1.0.1 build each request's URL by joining the Host header to the path and parsing the result again, without first validating the header against the grammar in RFC 9112 and RFC 3986. Starlette's router, by contrast, picks the handler from the original path. A middleware that decides from the reconstructed URL and the router that runs the handler can therefore read two different paths out of one request.
CVE-2026-48710 carries a CVSS score of 6.5: low impact on confidentiality and integrity, none on availability. The people who found it wrote on badhost.org that the number falls short for everything built on Starlette, because the flaw on its own leaks no information. Its effect is to switch off the controls that depend on request.url, and those are, in most deployments, the checks that guard prefixes such as /admin or /v1/models, separate tenants on a platform, enforce quotas or billing and protect against CSRF. How much harm follows is decided by the application behind those checks.
Timeline: from a vLLM audit to the KEV catalogue
The sequence of dates explains why a flaw disclosed in May is making headlines in September.
- January 2026. An analyst at X41 D-Sec locates the flaw while auditing vLLM under an engagement managed by OSTIF and funded by the Alpha-Omega project, as OSTIF and CSO Online report. The audit was aimed at the inference server; the flaw was in the library it depends on.
- 20 April. CVE-2026-42271 is published: a command injection in the LiteLLM API routes that test MCP server configurations. It is considered limited in impact because only a holder of valid proxy credentials can use it.
- 8 May. LiteLLM 1.83.7 fixes that injection and also updates the Starlette version it bundles, according to Horizon3's timeline.
- 26 May. OSTIF publishes the expanded BadHost details, citing slow adoption of Starlette 1.0.1 and vulnerable services that kept appearing on the internet. The Centre for Cybersecurity Belgium (CCB) issues its own warning on 28 May.
- 1 June. Horizon3 confirms that BadHost bypasses LiteLLM's authentication, turning CVE-2026-42271 into unauthenticated remote code execution. The full chain is rated CVSS 10.
- 9 June. CISA adds the LiteLLM flaw to the KEV catalogue. In Wiz's honeypots, the route is being used to install cryptocurrency miners.
- 26 and 27 August. Microsoft Threat Intelligence publishes its analysis of three intrusions into AI infrastructure, one of them on a LiteLLM gateway. A day later, Wiz publishes 90 days of honeypot telemetry.
- 2 September. CISA adds CVE-2026-48710 to the KEV catalogue. As The Hacker News reports, BOD 26-04 gives federal agencies until 16 September to remediate.
How one header fools the middleware
A web application works with two versions of every request: the unprocessed one that arrived from the network, and the objects the framework assembles on top to make the developer's life easier. In Starlette the router follows the first and the request.url object belongs to the second. If the Host header carries characters that, inside a URL, separate the path from the query string or the fragment, the rebuild moves those boundaries and request.url.path stops matching the path the router is going to execute.
Given that mismatch, an authentication middleware comparing request.url.path with a list of protected prefixes inspects a manipulated path, decides that no credentials are required and waves the request through. Starlette's router, which never looks at the Host header, runs the handler for the legitimate path with all its consequences. The attacker only has to know which path to aim for; no credentials and no user interaction are involved.
The footprint BadHost leaves is equally simple: requests whose Host header does not hold a valid hostname. Horizon3 lists it among its indicators of compromise, and that field is the first thing to check in the reverse proxy logs or, where there is no proxy, in those of the ASGI server.
The LiteLLM combination shows how BadHost extends the reach of another flaw. CVE-2026-42271 lets an authenticated user supply a command that the proxy will spawn as a subprocess when it tests an MCP server over stdio. Alone, that flaw needs credentials; preceded by BadHost, anyone on the internet reaches the route without them. Wiz describes attackers submitting a fictitious MCP server configuration whose command downloads and starts a miner, then answering with a correct MCP handshake so that the connection test is recorded as passed.
In those same honeypot sessions, Wiz watched attackers obtain the LiteLLM proxy's master credential by reading the state of the Python modules loaded in memory, with no need to search for it in files on disk.
Who is exposed, and under which conditions
OSTIF's list of affected software covers FastAPI, LiteLLM, vLLM, text-generation inference projects, most OpenAI-compatible proxies, MCP servers, agent runtimes, evaluation dashboards and model-management UIs. For scale, one figure from the State of AI in the Cloud report cited by Wiz: 90% of cloud environments run self-hosted AI software.
For BadHost to be exploitable, two conditions have to coincide. First, some middleware, dependency or decorator in the application makes security decisions from request.url or request.url.path. Second, requests reach the ASGI server (uvicorn, hypercorn, daphne or granian) without passing through a reverse proxy that rejects malformed Host headers. OSTIF states that nginx, Apache httpd and Cloudflare drop the malicious request in their default configuration, with one caveat: front ends terminating HTTP/3 or QUIC need separate testing, because their Host validation does not always behave like HTTP/1.1.
Both conditions coincide most often in the deployments that get the least attention: a LiteLLM proxy started with docker compose for a data team, a vLLM server on the lab GPU, or an internal MCP server listening on a high port. Few of those have nginx in front, and many can be reached from the corporate VPN or from a subnet that was once judged trustworthy. That ill-defined perimeter is BadHost's natural ground, and an attack surface assessment that covers the internal network tends to find it before the vulnerability scanner does.
Exposure comes with an inventory problem. Almost nobody installs Starlette deliberately; it arrives as a transitive dependency of FastAPI, LiteLLM or the MCP SDK. The GitLab advisory database ties fifteen Red Hat RHSA advisories to this single CVE, one for every product that bundled the library as a dependency. Without an SBOM or image scanning, the most reliable way to learn whether you are affected is to go through the containers one by one.
Detection and immediate containment
The earliest signal of BadHost is the Host header. Logging its value at the reverse proxy and alerting when it contains a slash, a question mark or a hash makes attempts visible before anything else runs. Where the ASGI server is exposed without a proxy, the application has to produce that log itself.
For AI gateways in particular, Horizon3 advises watching requests to /mcp-rest/test/connection and /mcp-rest/test/tools/list, two routes that hardly see traffic in a normal installation, along with any subprocess started from the LiteLLM process. Microsoft, which reconstructed a full intrusion from endpoint telemetry, publishes KQL hunting queries built on the same logic. They look for the gateway process as the parent of a shell, a Python interpreter or curl, and cross that with three kinds of signal:
- reads of /proc/1/environ, the file that inside a container exposes the environment variables of the main process;
- command lines mentioning DATABASE_URL or the LiteLLM_ProxyModelTable and LiteLLM_VerificationToken tables;
- outbound connections to IP addresses with no domain name or to out-of-band callback domains.
When one of those signals shows up on a LiteLLM gateway, containment runs in the opposite order to the usual playbook. Before stopping the container, treat the credentials as already copied: in the intrusion Microsoft reconstructed, the attacker's first action was to read the process environment and sift it for provider credentials, the master credential, connection strings and UI passwords. Rotating the model-provider credentials, the virtual keys issued by the proxy and the database connection string therefore comes before any other measure.
After the rotation, the AI provider accounts need checking for anomalous consumption, new models or credentials created without authorisation. That is the trail a threat hunting engagement follows once the attacker has left the server.
Patching, and what to do when you cannot patch yet
The fix for BadHost is Starlette 1.0.1; for LiteLLM it is version 1.83.7 or later, which also closes the command injection. The difficulty is that upgrading the package on the host achieves little when the library is packaged inside an image. OSTIF asks for every container, virtual environment and artefact that pins or vendors Starlette to be rebuilt and redeployed, and warns that the host's package list proves nothing.
If rebuilding is not feasible in the short term, three mitigations act on the conditions that make the flaw exploitable.
- Replace request.url and request.url.path with request.scope["path"] in any middleware, dependency or decorator that makes security decisions. It is the unreconstructed value, and OSTIF regards it as the durable fix, because this class of flaw can come back.
- Place a reverse proxy that rejects malformed Host headers in front of every ASGI-served application, and verify with the remote checker on badhost.org that the chosen configuration does so. The Belgian CCB also recommends avoiding path-based authentication and tying the credential check to the specific API endpoint.
- Take administrative and key-management surfaces off the internet. Microsoft proposes treating AI gateways as Tier 0 secret stores, the highest criticality level: authentication on both the API and the UI, restricted management ports, per-team virtual keys with spend limits instead of a shared master key, and secrets kept in a dedicated manager, not in the process environment variables.
Much of the hardening guidance for AI agents focuses on prompt injection and tool permissions. The cases published by Microsoft and Wiz show attackers who came in through a classic web flaw, read environment variables and queried a PostgreSQL database. For that reason, the AI agent and MCP server security audit we carry out at Hard2bit devotes as much time to the HTTP layer and the deployment as to the agent.
What to watch over the coming weeks
A flaw's arrival on the KEV catalogue is usually followed within days by its inclusion in mass scanners. Wiz, deferring to external researchers, connects exploitation of the LiteLLM chain to operators linked to the Qilin ransomware; Microsoft describes credential theft, persistence via SSH keys and cron entries, and cryptomining. Neither report yet records BadHost being used against ordinary FastAPI applications outside the AI ecosystem. That is the development to follow, because the surface is vastly larger and the flaw is the same.
The Langflow IDOR and the LLMjacking campaigns had already shown that AI infrastructure concentrates credentials and that whoever attacks it knows where to look. BadHost adds to that lesson an entry point that lives outside the AI application, in the web library serving it.
There is a second front: SDKs and tools that embed Starlette and may not surface in any package scan. An MCP server written with the Python SDK and published as an image six months ago contains whatever Starlette version existed at the time. Which version the image includes and when it was last rebuilt: that is the question a vulnerability management programme should put to the vendor this week.
This article combines technical information from public advisories with third-party research (OSTIF, X41 D-Sec, Horizon3, Wiz and Microsoft), as available at the date of publication. The configurations and measures described are indicative: every deployment should validate them in a test environment before applying them in production. Attributions to threat groups and the scope of the activity may evolve as investigations progress.