Typebot: Server-Side Request Forgery im HTTP-Request-Block über eine Redirect-Umgehung der SSRF-Allowlist

Der HTTP-Request-Block von Typebot prüft nur die zuerst angefragte URL gegen die SSRF-Allowlist, weil ein eigenes fetch die validierende Fetch-Instanz überschreibt, sodass ein Angreifer-Host mit einer 302/307-Weiterleitung auf interne Adressen und AWS-IMDSv1 zeigt.

Advisory-ID: TP-2026-052
Produkt: Typebot (Open-Source-Baukasten für Chatbots und Konversationsformulare, self-hosted)
Schwachstellentyp: Server-Side Request Forgery (CWE-918)
CVE: pending
CVSS 3.1: 7.7 (Hoch) · CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N
Hersteller-Advisory: GHSA-gmm5-4r2j-mq64
Betroffene Versionen: Typebot <= 3.17.2
Behoben in: Typebot 3.18.0
Gemeldet: 4. Juni 2026

Zusammenfassung

Typebot ist ein self-hosted Baukasten für Chatbots und Konversationsformulare, dessen HTTP-Request-Block (Webhook) standardmäßig server-seitig läuft. Der Block soll durch safeKy geschützt sein, das jeden Redirect-Sprung erneut gegen die SSRF-Allowlist prüft und einen DNS-Rebind-sicheren Dispatcher setzt. Der Aufrufer übergibt jedoch ein eigenes, ungeschütztes fetch, das die validierende Fetch-Instanz überschreibt, sodass nur die zuerst angefragte URL geprüft wird und Redirect-Ziele ungeprüft bleiben. Ein Bot-Autor zeigt mit dem Block auf einen Angreifer-Host, der die Anfangsprüfung besteht und dann per 302/307 auf ein internes, Loopback- oder IMDSv1-Ziel weiterleitet, wobei Methode, Header und Body die Weiterleitung überstehen. So werden interne Dienste und die temporären AWS-IAM-Zugangsdaten über IMDSv1 erreichbar. Dies ist eine unvollständige Behebung von CVE-2025-64709.

Ursache

Der Block läuft standardmäßig server-seitig (isExecutedOnClient=false, packages/blocks/integrations/src/httpRequest/constants.ts:21) und soll durch safeKy geschützt sein, dessen Fetch jeden Redirect-Sprung mit redirect:"manual" und validateHttpReqUrl(location) neu prüft und einen DNS-Rebind-sicheren undici-Dispatcher setzt (packages/lib/src/ky.ts:72/99/113). executeHttpRequestBlock.ts:289-295 übergibt jedoch sein eigenes, ungeschütztes fetch (einfaches rebuildFetchWithoutChunkedEncoding mit nativem Fetch, redirect:"follow", ohne Dispatcher) an safeKy(request.url, omit(request,"url")) (:312), und ky 1.2.4 überschreibt die Instanz-Default-Fetch skalar mit diesem fetch, sodass die validierende Fetch-Instanz nie läuft und nur die Anfangs-URL geprüft wird (:247). validateHttpReqHeaders (validateHttpReqUrl.ts:141, BLOCKED_HEADERS) blockt auf der Erstanfrage weiterhin die Metadaten-Header von AWS, GCP und Azure, sodass IMDSv2, GCP und Azure gemindert bleiben, aber AWS IMDSv1 ohne Header erreichbar ist. Basis-Angreifer ist jeder registrierte Nutzer (offene Registrierung ist Standard); anonym wird der Angriff, wenn der Autor eine vorbelegbare {{variable}} in URL, Header oder Body platziert, die durch parseVariables läuft (:180-228).

Proof of Concept

# Der Angreifer-Host besteht die Anfangsprüfung und leitet dann intern weiter:
#   https://attacker.example/redirect  ->  302 Location: http://172.16.0.10/…

# Anonymer Chat-Start, der den HTTP-Request-Block auslöst:
POST /api/v1/typebots/<publicId>/startChat
# Der Server folgt der 302 zum internen Ziel und gibt dessen Body an den Aufrufer zurück.
# Ein 307 + POST trägt Methode, JSON-Body und einen X-Injected-Header zum internen Ziel.

In der Live-Verifikation auf Version 3.17.1 (ky 1.2.4) folgte der Server nach einem anonymen startChat einer 302 auf einen nur intern erreichbaren Dienst im Bereich 172.16/12 und gab dessen Body an den unauthentifizierten Aufrufer zurück (lesbare SSRF), während dieselbe interne bzw. Link-Local-URL direkt gesetzt blockiert wurde (Access to link-local addresses (169.254.0.0/16) is not allowed, Kontrolllauf). Eine 307 mit POST trug Methode, JSON-Body und einen eigenen X-Injected-Header zum internen Ziel, was die Schreibfähigkeit belegt.

Auswirkung

  • Lesbare SSRF vom Server aus auf interne, Loopback- und Link-Local-Dienste, deren Antwort an den Aufrufer zurückgegeben wird.
  • Zugriff auf AWS IMDSv1 und damit auf temporäre IAM-Zugangsdaten der Instanz (IMDSv2, GCP und Azure bleiben durch die Header-Sperre gemindert).
  • Über 307 mit POST Übertragung von Methode, Body und Headern an interne Ziele, also zustandsändernde Anfragen statt nur eines blinden GET.
  • Basis-Angreifer ist jeder registrierte Nutzer bei standardmäßig offener Registrierung; anonym, sobald eine vorbelegbare Variable in URL, Header oder Body steht.

Referenzen

Steckt so etwas in Ihrer Software?

Diese Schwachstelle hat unser Team im Rahmen seiner Arbeit gefunden. Lassen Sie Ihre Anwendungen von denselben Spezialisten prüfen, mit einem Penetrationstest von turingpoint.