← Back to Feed CACHED · 2026-09-04 07:09:44 · CACHE_KEY CVE-2026-48710
CVE-2026-48710 · CWE-444 · Disclosed 2026-05-26

Starlette is a lightweight ASGI framework/toolkit.

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

A single question mark in the Host header unlocks every door your middleware thought it had locked

CVE-2026-48710, dubbed BadHost, is a Host header validation bypass in Starlette versions 0.8.3 through 1.0.0 (fixed in 1.0.1). Starlette reconstructs request.url by concatenating the raw HTTP Host header with the request path — f"{scheme}://{host_header}{path}" — without validating the Host value against RFC 9112 / RFC 3986. By injecting a ?, #, or / into the Host header, an attacker makes request.url.path resolve to / (a public route) while the ASGI router still dispatches the request to the *actual* target path (e.g., /admin). Any middleware or endpoint that gates access using request.url.path instead of scope['path'] is instantly bypassed. Because Starlette underpins FastAPI (490M+ monthly PyPI downloads), vLLM, LiteLLM, and most MCP servers, the blast radius is enormous.

The vendor scored this MEDIUM 6.5, which dramatically undersells the real-world risk. The standalone CVSS assessment captures only Confidentiality:Low / Integrity:Low, treating it as a generic information-disclosure-class bug. In practice, the exploit is unauthenticated, requires zero user interaction, works with a single curl command, is KEV-listed as of September 2, 2026, and is already being chained in the wild with CVE-2026-42271 to achieve unauthenticated RCE against LiteLLM gateways — delivering XMRig cryptominers, harvesting secrets from PostgreSQL, and establishing persistence. Microsoft Threat Intelligence published a detailed write-up of the campaign. The vendor MEDIUM label is dangerously wrong for any team running Starlette-based services that are network-reachable.

"Trivial Host-header trick bypasses auth on any Starlette/FastAPI app; KEV-listed, actively chained for RCE."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Identify Starlette/FastAPI target

The attacker scans for HTTP services returning Starlette or FastAPI fingerprints (default error pages, /docs or /openapi.json endpoints). Shodan and FOFA queries for server: uvicorn or fastapi paths return hundreds of thousands of results. Public scanners at badhost.org automate detection.
Conditions required:
  • Target runs Starlette 0.8.3–1.0.0 or FastAPI depending on vulnerable Starlette
  • Service is network-reachable (internet or internal network)
Where this breaks in practice:
  • Well-configured reverse proxies (nginx, Envoy, Cloudflare) may normalize or reject malformed Host headers before they reach Starlette
Detection/coverage: Snyk, Semgrep rules, and CodeQL queries published by X41. Nuclei template available via Bhanunamikaze/BadHost-CVE-2026-48710-Exploit.
STEP 02

Craft malicious Host header

The attacker sends a request like GET /admin with Host: legitimate.com? (appending a ? character). Starlette concatenates this into https://legitimate.com?/admin and re-parses the result. The ? turns /admin into a query parameter, so request.url.path becomes / — which matches the public root route. The ASGI router, however, dispatches based on the raw scope path, which is still /admin.
Conditions required:
  • Application uses middleware that checks request.url.path for authorization decisions
  • No upstream proxy strips or rejects the malformed Host header
Where this breaks in practice:
  • Applications using scope['path'] directly for auth checks are not affected
  • Some load balancers reject Host headers containing ? or #
Detection/coverage: WAF rules matching ?, #, or / in Host header values. Access logs showing Host headers with URI-reserved characters.
STEP 03

Bypass path-based authorization

The middleware sees request.url.path == '/' and allows the request through. The router dispatches to /admin (or any other protected endpoint). The attacker now has unauthenticated access to every endpoint that was protected by path-based middleware — including admin panels, API key management, model configuration endpoints, and health/debug routes that expose internal state.
Conditions required:
  • Authorization logic relies on request.url or request.url.path
Where this breaks in practice:
  • Applications using token-based auth (JWT/OAuth) validated at the endpoint level are unaffected by the path bypass alone
  • Role-based checks inside the endpoint handler still apply
Detection/coverage: Anomalous 200 responses to admin paths from unauthenticated sessions. SIEM correlation of Host header anomalies with successful admin endpoint access.
STEP 04

Chain for RCE (LiteLLM campaign)

In the documented wild campaign, attackers chain BadHost with CVE-2026-42271 (LiteLLM command injection, CVSS 8.7). BadHost bypasses LiteLLM's auth middleware, then the command injection payload executes arbitrary OS commands. Horizon3.ai documented the full chain. Attackers deploy Python droppers, harvest runtime secrets and PostgreSQL credentials, install XMRig miners, and establish persistence via cron.
Conditions required:
  • Target is a LiteLLM gateway (or similar Starlette-based app with a secondary injection flaw)
  • LiteLLM version < 1.83.7
Where this breaks in practice:
  • Requires a second vulnerability for RCE; BadHost alone yields auth bypass, not code execution
  • Network segmentation may limit lateral movement from compromised LLM gateway
Detection/coverage: EDR alerts on unexpected child processes from Python/uvicorn. GreyNoise tags for LiteLLM scanning activity. Microsoft Defender for Cloud workload alerts.
03 · Intelligence Metadata

The supporting signals.

In-the-Wild StatusActively exploited. CISA KEV-listed 2026-09-02. Microsoft Threat Intelligence documented campaigns chaining BadHost + CVE-2026-42271 against LiteLLM gateways for cryptomining and secret theft.
Proof-of-ConceptPublic and trivial. One-line curl: curl -H 'Host: target?' http://target/admin. Dedicated scanner at badhost.org. GitHub repos: Bhanunamikaze/BadHost-CVE-2026-48710-Exploit, alon710 gist.
EPSS0.11042 (11.04%) — 96th percentile. Top 4% of all CVEs by predicted exploitation probability.
KEV StatusYES — Added 2026-09-02. BOD 22-01 / BOD 26-04 remediation deadline applies to FCEB agencies.
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N — Network-accessible, no auth, no interaction. The Low/Low CIA impact is what keeps the vendor score at 6.5 but understates chained outcomes.
Affected VersionsStarlette 0.8.3 – 1.0.0. FastAPI all versions depending on vulnerable Starlette. LiteLLM < 1.83.7. vLLM and MCP servers using bundled Starlette < 1.0.1.
Fixed VersionStarlette 1.0.1+. FastAPI users must pin starlette>=1.0.1. LiteLLM 1.83.7+.
Scanning/Exposure DataShodan queries for server: uvicorn return 200K+ hosts. badhost.org provides a free online scanner. Snyk reports active exploitation attempts observed in telemetry.
Disclosure Date2026-05-26 (coordinated disclosure). KEV addition 2026-09-02.
ReporterVulnerability reported by the Starlette maintainers (Kludex). Campaign analysis by Horizon3.ai, Microsoft Threat Intelligence, and Oligo Security.
04 · The Call

noisgate verdict.

Final Verdict
UPGRADED to HIGH (8.0/10)

The single most decisive factor is the active KEV listing combined with documented in-the-wild exploitation chains converting a MEDIUM-rated auth bypass into unauthenticated RCE against LLM gateways. The trivial exploit complexity (one curl command, no auth, no user interaction) and the massive installed base (FastAPI's 490M+ monthly PyPI downloads) eliminate any friction-based argument for keeping this at MEDIUM.

HIGH Vulnerability mechanism and exploitability
HIGH Active exploitation and KEV status
MEDIUM Fraction of deployments reachable without upstream proxy normalization

Why this verdict

  • Trivial exploitability: One-line curl command, unauthenticated, no user interaction. Attack complexity is effectively zero for any exposed Starlette service without a normalizing reverse proxy.
  • KEV + active campaigns: CISA added this to KEV on 2026-09-02 citing active exploitation. Microsoft documented real-world campaigns chaining BadHost with CVE-2026-42271 for RCE, cryptomining, and credential harvesting against LiteLLM gateways.
  • Massive installed base: Starlette is the ASGI layer under FastAPI (490M+ monthly PyPI downloads), vLLM, LiteLLM, and MCP servers. The affected population is not a niche product — it is core AI/ML infrastructure.
  • Role multiplier: Starlette/FastAPI is canonically deployed as (c) high-value roles: LLM inference gateways (LiteLLM, vLLM) that hold API keys and model access, MCP agent control planes, and internal API tiers that front production databases. Auth bypass on an LLM gateway yields access to all configured provider API keys, model configurations, and connected data stores. The documented chain ends in full host compromise + secret harvesting + lateral movement — blast radius is host-to-fleet. Because Starlette *is* the framework for these high-value roles (not an incidental dependency), >=10% of Starlette installs occupy high-value positions. Verdict floor: HIGH.
  • Friction offset (partial): Reverse proxies (nginx, Envoy, Cloudflare) that normalize Host headers do block the attack. This prevents an upgrade to CRITICAL because a meaningful fraction of production deployments sit behind such proxies. However, dev/staging instances, directly-exposed uvicorn services, and internal network services often lack this protection.

Why not higher?

The standalone vulnerability is an authentication bypass, not direct remote code execution. Achieving RCE requires chaining with a second vulnerability (e.g., CVE-2026-42271 in LiteLLM). Additionally, well-configured reverse proxies that validate Host headers per RFC 9112 neutralize the attack entirely. The CVSS impact is C:L/I:L/A:N for the standalone flaw, and the blast radius requires a secondary bug to reach fleet-scale compromise.

Why not lower?

KEV listing with documented active exploitation campaigns immediately disqualifies MEDIUM or below. The exploit is unauthenticated, requires zero complexity, has public PoC tooling and dedicated scanners, and affects the most popular Python web framework ecosystem. The high-value deployment roles (LLM gateways, AI agent infrastructure) mean the auth bypass alone exposes API keys, model configs, and internal endpoints even without chaining for RCE.

05 · Compensating Control

What to do — in priority order.

  1. Deploy or verify Host header validation on your reverse proxy — Configure nginx (server_name directive with strict matching), Envoy (strict host matching in route config), or Cloudflare (managed rules) to reject or normalize Host headers containing ?, #, or / characters before traffic reaches Starlette. This is the most effective immediate mitigation — deploy within 3 days per noisgate mitigation SLA since this is KEV-listed with active exploitation, overriding the standard 30-day HIGH timeline.
  2. Audit middleware auth logic for request.url.path usage — Search your codebase for request.url.path or request.url in authorization checks. Replace with request.scope['path'] which uses the raw ASGI path unaffected by Host header manipulation. Semgrep rule: pattern: request.url.path. Deploy code changes within the mitigation window.
  3. Pin starlette>=1.0.1 in all requirements files — Run pip install --upgrade starlette>=1.0.1 across all environments. For FastAPI projects, verify the resolved Starlette version with pip show starlette. For LiteLLM, upgrade to >=1.83.7. Prioritize internet-facing and LLM gateway deployments first.
  4. Monitor for Host header anomalies in access logs — Create SIEM alerts for HTTP requests where the Host header contains ?, #, or path separators. Correlate with successful (2xx) responses to admin or protected endpoints. This provides detection coverage while patching is in progress.
What doesn't work
  • WAF path-based rules alone — The attack manipulates the Host header, not the URL path. Standard WAF rules that inspect the request URI will not catch the malformed Host header unless specifically configured for Host header validation.
  • Token-based auth at the middleware layer using request.url — If your JWT/OAuth validation middleware uses request.url.path to decide *whether* to enforce auth (e.g., skipping auth for /health), the bypass still works even though the token validation logic itself is sound.
  • Network segmentation without Host header normalization — Putting the service on an internal network reduces exposure but does not eliminate it; any internal attacker or compromised adjacent host can still exploit the flaw.
06 · Verification

Crowdsourced verification payload.

Run this script on any host with pip access to check installed Starlette versions. Execute as the same user that runs your Python applications: bash check_badhost.sh. No elevated privileges required.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_badhost.sh — Detect CVE-2026-48710 (BadHost) in installed Starlette
# Usage: bash check_badhost.sh
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -euo pipefail

VULN_CVE="CVE-2026-48710"
FIXED_VERSION="1.0.1"

echo "[*] Checking for $VULN_CVE (Starlette BadHost)"

# Check if pip is available
if ! command -v pip &>/dev/null && ! command -v pip3 &>/dev/null; then
  echo "UNKNOWN — pip not found. Check Python environments manually."
  exit 2
fi

PIP_CMD=$(command -v pip3 2>/dev/null || command -v pip 2>/dev/null)

# Get installed starlette version
INSTALLED=$($PIP_CMD show starlette 2>/dev/null | grep -i '^Version:' | awk '{print $2}')

if [ -z "$INSTALLED" ]; then
  echo "UNKNOWN — starlette is not installed in this Python environment."
  echo "[*] Check other virtualenvs: find / -name 'starlette' -path '*/site-packages/*' 2>/dev/null"
  exit 2
fi

echo "[*] Installed starlette version: $INSTALLED"
echo "[*] Fixed version: >= $FIXED_VERSION"

# Compare versions using sort -V
LOWEST=$(printf '%s\n%s\n' "$INSTALLED" "$FIXED_VERSION" | sort -V | head -n1)

if [ "$LOWEST" = "$FIXED_VERSION" ] || [ "$INSTALLED" = "$FIXED_VERSION" ]; then
  echo "PATCHED — starlette $INSTALLED >= $FIXED_VERSION"
  exit 0
else
  echo "VULNERABLE — starlette $INSTALLED < $FIXED_VERSION"
  echo "[!] Upgrade immediately: pip install 'starlette>=$FIXED_VERSION'"
  exit 1
fi
07 · Bottom Line

If you remember one thing.

TL;DR
Patch immediately. CVE-2026-48710 was added to CISA KEV on September 2, 2026 with confirmed active exploitation — this overrides the standard noisgate mitigation SLA and demands action within hours, not days. Monday morning: (1) run the verification script across all Python environments to inventory vulnerable Starlette installs, (2) upgrade starlette to >=1.0.1 and litellm to >=1.83.7 on all internet-facing and LLM gateway hosts first, (3) verify your reverse proxy (nginx, Envoy, Cloudflare) rejects or normalizes Host headers containing ?, #, or / — this is your fastest compensating control if patching takes time, (4) audit all custom middleware for request.url.path usage and switch to scope['path']. The noisgate remediation SLA for HIGH is 180 days for the full fleet, but KEV-listed active exploitation means you should treat internet-facing instances as a same-day emergency and complete internal hosts within 30 days.

Sources

  1. Snyk Vulnerability Database — SNYK-PYTHON-STARLETTE-16881242
  2. Horizon3.ai — CVE-2026-42271 Chained with CVE-2026-48710
  3. CISA KEV Addition — September 2, 2026
  4. Microsoft Threat Intelligence — Securing AI Gateways
  5. Oligo Security — LiteLLM RCE Detection and Blocking
  6. The Hacker News — LiteLLM Flaw Exploited in the Wild
  7. BadHost PoC and Exploit Repository
  8. Belgium CCB Advisory — Starlette Framework Vulnerability
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.