BadHost (CVE-2026-48710): Eine Zeile im Host-Header hängt Auth aus — Starlette, FastAPI und jeder MCP-Server unter 1.0.1 sind die Linie
27. Mai 2026. X41 D-Sec hat am 22. Mai im Rahmen einer OSTIF-finanzierten vLLM-Audit-Runde die BadHost-Schwachstelle (CVE-2026-48710) im Starlette-ASGI-Framework offengelegt. Eine einzige Zeile im HTTP-Host-Header reicht, um path-basierte Auth-Middleware auszuhebeln; request.url.path wird aus dem Host-Header rekonstruiert, das ASGI-Routing dagegen aus dem rohen Pfad — ein klassisches Path-Confusion-Pattern, das in jedem Python-Stack mit FastAPI, vLLM, LiteLLM oder einem Model-Context-Protocol-Server greift. Starlette 1.0.1 vom 21.05. schließt die Lücke; für Moselwal-Kunden mit eigenem MCP-Stack oder FastAPI-Backends gehört der Bump in die nächste Wartungs-Runde.
![Aufsicht-Stillleben auf einer matt-dunklen Schieferfläche als Arbeitstisch eines Routing-Auditors. Im Zentrum eine kreisrunde niedrige Sortier-Tablette aus brüniertem Messing mit einem dünnen Mittel-Steg, der die Tablette in zwei Pigeonholes teilt — die linke gestempelt /public/discovery, die rechte gestempelt /admin/settings, beide in monospaced Letterpress. Quer über dem Steg liegt ein einzelner cremefarbener Brief: die obere Hälfte gestempelt Host: example.com/.well-known/ ragt in die /public-Pigeonhole, die untere Hälfte mit dem Slip path: /admin/settings ragt in die /admin-Pigeonhole. Auf der oberen /public-Hälfte sitzt ein einzelner oxblutroter Wachstropfen mit einem brünierten Messing-Petschaft als Auth-Stempel. Links unten ein aufgeschlagenes leinenbespanntes Audit-Hauptbuch mit drei monospaced Bleistift-Einträgen, einer davon lesbar scope["path"], daneben ein cremefarbenes Karteikärtchen mit der monospaced Letterpress-Aufschrift CWE-444. Rechts oben im Negativraum ein brünierter Messing-Stempel mit Walnussgriff und ein zweites Karteikärtchen mit der Letterpress-Aufschrift Starlette 1.0.1. Kühles Studio-Schlüssellicht von oben links, sanftes warmes Rim-Licht von unten rechts; Hintergrund verläuft ins Schiefergrau und Beinahe-Schwarz am rechten Bildrand, für das Title-Overlay frei.](/fileadmin/_processed_/0/c/csm_mcp-bad-host_03bbdc9336.png)
TL;DR — die 90-Sekunden-Zusammenfassung
- Was wurde veröffentlicht?
Eine Authentication-Bypass-Schwachstelle in Starlette < 1.0.1, dem ASGI-Framework, auf dem FastAPI, vLLM, LiteLLM, das offizielle Model-Context-Protocol-Python-SDK und nach OSTIF-Schätzung mehr als 400.000 GitHub-Repositories aufsetzen. CVE-2026-48710, Klasse CWE-444 (Inconsistent Interpretation of HTTP Requests / HTTP Request Smuggling), öffentlich seit 22.05.2026 zusammen mit der Scanner-Domain badhost.org.
- Wie schwer?
X41 D-Sec stuft CVSS 7.0 (High) ein, Starlette-Maintainer 6.5 (Moderate). Die Differenz hängt an einer Annahme: der Maintainer sieht Path-based Auth als Anti-Pattern und damit die Klasse als enge, der Auditor sieht Path-based Auth als Default-Pattern in MCP-Servern, FastAPI-Auth-Decorators und Reverse-Proxy-Setups — also als breite Realität. X41 hat in CodeQL-Scans mehrere Stacks identifiziert, in denen der Bypass über sekundäre Effekte zu RCE eskalierbar war.
- Welcher technische Hebel?
Starlette baut
request.urlper String-Konkatenation aus Host-Header und Pfad. Wenn der Host-Header ein/,?oder#enthält, verschiebt sich die URL-Grenze beim Re-Parse; der ASGI-Server routet weiterhin gegen den rohen Pfad inscope["path"], die Middleware liest aberrequest.url.pathund sieht etwas anderes.- Warum ist MCP besonders exponiert?
Die Model-Context-Protocol-Spezifikation schreibt unauthentifizierte OAuth-Discovery-Endpunkte vor —
/.well-known/oauth-authorization-server,/.well-known/oauth-protected-resource,/.well-known/openid-configurationsind per Definition öffentlich. Genau diese Pfade liefern die zuverlässigste Host-Header-Substitution. Ein MCP-Server, der path-prefix-Auth für/tools,/resourcesoder/promptsmacht, ist mit den drei öffentlichen Discovery-Pfaden in der Hand des Angreifers.- Bin ich als Moselwal-Kunde betroffen?
Direkt, wenn Sie einen eigenen MCP-Server (Anthropic-Connector, interne Tools), eine FastAPI-Anwendung, ein vLLM- oder LiteLLM-Deployment oder einen OpenAI-Shim-Proxy laufen haben. Indirekt über transitive Dependencies in nahezu jedem modernen Python-AI-Stack — Starlette ist die Pflicht-Dependency von FastAPI und damit von einer breiten Klasse von Agent-Harness-Komponenten.
- Sofort-Mitigation ohne Patch?
Bei Reverse-Proxy-Setup (nginx, Traefik, Caddy, AWS ALB): Host-Header serverseitig auf die erwartete Domain normalisieren und Slashes, Fragezeichen, Hash-Zeichen im Host-Header zurückweisen. In der Auth-Middleware:
scope["path"]verwenden stattrequest.url.path— das ist der Pfad, gegen den der Router tatsächlich entscheidet. Beides löst die Klasse, aber der Pull auf Starlette 1.0.1 ist der kürzere Weg.
Was ist passiert
Die Disclosure-Kette ist nüchtern dokumentiert. X41 D-Sec identifizierte BadHost am 27. Januar 2026 im Rahmen einer von OSTIF (Open Source Technology Improvement Fund) finanzierten Audit-Runde des vLLM-Inferenz-Servers. Am 4. Februar ging die koordinierte Meldung an die Starlette-Maintainer mit Proof-of-Concept; Acknowledgment am 5. Februar. Ein Patch-Vorschlag lag am 1. März vor, das eigentliche Release Starlette 1.0.1 erschien aber erst am 21. Mai — knapp drei Monate nach dem Patch-Vorschlag. Am 22. Mai ging die Disclosure öffentlich, parallel mit der Scanner-Domain badhost.org und X41s Detektor-Werkzeug. Die Lage ist seitdem auf einschlägigen Tech-Briefings (CSO Online, InfoWorld, Cyber Kendra, Help Net Security, SC Media) breit dokumentiert; der Hacker-News-Diskussionsfaden hat dreistellige Kommentarzahlen erreicht. Das BSI hat zum Stand heute keine eigene Warnung publiziert.
Technische Einordnung
Strukturell ist BadHost ein Path-Confusion-Vorfall in CWE-444. Starlette rekonstruiert request.url über eine String-Konkatenation f"{scheme}://{host}{path}{query}{fragment}", wobei host direkt aus dem HTTP-Host-Header kommt. Anschließend wird die zusammengebaute URL erneut geparsed; ein / im Host-Header verschiebt dabei die Pfad-Grenze, ein ? die Query-Grenze, ein # die Fragment-Grenze. Das Resultat: request.url.path ist eine andere Zeichenkette als scope["path"]. Der ASGI-Server (uvicorn, hypercorn) routet gegen scope["path"], jede Middleware, die request.url.path auswertet, sieht aber die manipulierte Variante.
In CVSS-Begriffen, und hier liegt die Diskrepanz zwischen Maintainer und Auditor: AV:N (network), AC:L (low complexity), PR:N (no privileges — ein offener Endpunkt wie ein MCP-Discovery-Pfad genügt), UI:N (no user interaction), Scope:Changed oder Unchanged je nach Stack, C:H/I:H/A:L. Der Maintainer geht von Scope:U und niedrigerer Confidentiality aus, weil er Path-based Auth als Anti-Pattern liest; X41 geht von Scope:C aus, weil in den real existierenden FastAPI- und MCP-Codebasen die Auth genau über request.url.path läuft und der Auth-Bypass damit den gesamten geschützten Endpunkt-Bereich öffnet.
Bedeutung für den Mittelstand
Bei unserer Kundschaft sitzt Starlette in drei Klassen von Stacks. Erstens: eigener MCP-Server für interne Tool-Integration in Claude- oder Anthropic-Agent-Workflows. Das ist die Klasse mit der schärfsten Exposure — die OAuth-Discovery-Pfade sind öffentlich, die Tool-Endpunkte sind durch path-prefix-Auth geschützt, und genau diese Architektur ist das BadHost-Lehrbuchbeispiel. Zweitens: FastAPI-Backends in Plattform-Diensten (Form-Eingaben, Webhook-Endpunkte, AI-Funktions-Wrapper, interne Verwaltungs-APIs). Hier ist die Auth-Klasse heterogener, aber path-prefix-Checks sind ein verbreitetes Muster. Drittens: transitive Exposure über vLLM (Inferenz-Server für offene Modelle) und LiteLLM (OpenAI-Shim-Proxy für Multi-Model-Routing); beide nutzen Starlette als HTTP-Schicht, beide sind im Self-Hosted-Sovereign-Hosting-Trend der letzten Monate breit eingesetzt.
Compliance-seitig wirkt der Vorfall auf mehreren Achsen. NIS-2 Art. 21 verlangt Patch-Disziplin entlang der Lieferkette, und Starlette ist Lieferketten-Bestandteil. BSI APP.6 (Allgemeine Software) und APP.4 (Business-Anwendungen) tragen den Befund; eine MCP-Server-Architektur fällt zudem unter BSI APP.4.2 (Datenbanken) oder APP.4.3 (Server-Webanwendungen), je nach Ausprägung. DSGVO Art. 32 trifft jede Pipeline, die personenbezogene Daten über den MCP-Tool-Layer reicht — ein Auth-Bypass auf einem Tool-Endpunkt ist eine Verletzung der Vertraulichkeit. Für DORA-Pflichtige (Finanzdienstleister) wandert der Befund in die IKT-Drittparteienregister-Erfassung, für MaRisk-Häuser in die nächste IKS-Runde. Der EU AI Act Art. 25 (Deployer-Pflichten) ergänzt für KI-Systeme im hochriskanten Anwendungsbereich.
Bedeutung für die technische Entwicklung
Methodisch zeichnet sich eine Spur ab, die wir in der Daily-News-Welle der letzten zwei Wochen wiederholt gesehen haben. OSTIF-finanzierte Audits liefern reproduzierbar substantielle Befunde an offenen Open-Source-Komponenten — das war bei der Mythos-/Glasswing-Audit-Welle auf Symfony und Twig im April und Mai der Fall, und es ist hier in der vLLM-Audit-Runde wieder so. Die Finanzierungs-Schicht ist nicht nebensächlich: ein Open-Source-Maintainer-Team allein hätte die drei Monate zwischen Patch-Vorschlag und Release wahrscheinlich nicht in dieser Qualität überbrücken können, wenn die Disclosure-Kette nicht von einer dedicated Audit-Organisation getragen worden wäre. Die Lehre für den Mittelstand ist nicht „mehr Open Source verwenden“ oder „weniger“, sondern: bei Stack-Komponenten mit hohem Verbreitungsgrad lohnt die Prüfung, ob eine dokumentierte Audit-Quelle existiert.
Architektonisch sitzt die schärfste Lehre in der Auth-Disziplin. Path-based Auth-Middleware ist nicht per se ein Anti-Pattern — sie ist in vielen Architekturen das einzige praktikable Modell, etwa wenn der Reverse-Proxy keinen Zugriff auf die interne Auth-Logik hat oder wenn die Anwendung selbst die Auth-Regeln trägt. Was die Klasse aber verlangt, ist die Prüfung der Quelle: scope["path"] (also der Pfad, den der ASGI-Server tatsächlich routet) ist die einzige verlässliche Zeichenkette für eine Auth-Entscheidung; request.url.path ist das Convenience-Objekt, das jederzeit kippen kann, sobald eine Komponente in der Kette einen Header anders interpretiert. Diese Trennung gilt nicht nur für Starlette; sie ist eine generelle Disziplin für alle HTTP-Frameworks, in denen URL und Pfad aus verschiedenen Quellen rekonstruiert werden.
Konkrete Handlungsempfehlung
In dieser Reihenfolge. Erstens, inventarisieren Sie heute alle Python-ASGI-Stacks mit Starlette als direkter oder transitiver Dependency: eigene MCP-Server, FastAPI-Backends, vLLM-/LiteLLM-Deployments, OpenAI-Shim-Proxies, Agent-Harness-Komponenten. pip show starlette und pipdeptree --reverse starlette liefern den Überblick. Zweitens, ziehen Sie Starlette auf 1.0.1 in einer Test-Pipeline und fahren Sie einen Smoke-Test gegen die Auth-Pfade (interner Curl mit manipuliertem Host-Header, Test gegen die Discovery-Endpunkte). Drittens, bei Architekturen mit path-prefix-Auth: prüfen Sie, ob die Middleware scope["path"] oder request.url.path verwendet, und wechseln Sie im zweiten Fall auf scope["path"]. Viertens, im Reverse-Proxy (nginx, Traefik, Caddy, AWS ALB) Host-Header-Normalisierung aktivieren — Slashes, Fragezeichen und Hash-Zeichen im Host-Header zurückweisen. Wenn diese vier Schritte aus eigener Kraft nicht laufen, sprechen Sie mit uns: Moselwal richtet MCP- und FastAPI-Stacks, in denen die Auth-Disziplin entlang scope["path"] und nicht entlang request.url.path geführt wird.
Dieser Beitrag spiegelt unsere technische und strategische Einschätzung. Er ersetzt keine Rechtsberatung und keine Datenschutz-Folgenabschätzung.
Quellen
- OSTIF — Disclosing the BADHOST Vulnerability in Starlette (22.05.2026)
- badhost.org — CVE-2026-48710 Starlette Host-Header Auth Bypass, Scanner und Detail-Beschreibung (22.05.2026)
- CSO Online — FastAPI-based AI tools exposed to authentication bypass by flaw in Starlette framework (22.05.2026)
- Cyber Kendra — BadHost (CVE-2026-48710): One Rogue Header Line Unlocks Your Entire AI Stack (22.05.2026)
- OffSeq Threat Radar — CVE-2026-48710 CWE-444 Inconsistent Interpretation of HTTP Requests in Kludex starlette (Stand 22.05.2026)

