FlawOpen

flawopen.com/Teardowns/cve-2026-5027-langflow-multipart-file-write

● CVE-2026-5027 · CVSS 8.8[1], [2] · Haute
Recherche · FlawOpen

Langflow CVE-2026-5027 : traversal dans les fichiers multipart

CVE-2026-5027 permettait d’écrire hors du dossier d’envoi de Langflow par traversal. GTIG signale une exploitation ; passez à 1.9.0+.[1], [2], [6]

Vecteur CVSSCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H[1], [2]
💡 Explication en Langage Simple (ELI5)

Un centre de courrier accepte un colis dont l’expéditeur choisit l’étiquette et la destination. Si l’employé assemble cette étiquette au dossier sans vérifier le chemin final, le colis peut sortir du centre. La route d’envoi de Langflow faisait confiance au nom multipart, tandis que le stockage ne vérifiait pas séparément que le chemin restait dans le dossier autorisé.[2], [3]

Concepts Clés et Termes

CVE-2026-5027
Identifiant attribué par Tenable à un path traversal dans le nom multipart de POST /api/v2/files de Langflow : CWE-22, CVSS 3.1 8,8 et privilèges faibles requis.[1], [2]
Nom multipart
Nom fourni par le client dans Content-Disposition d’un envoi multipart. C’est une entrée non fiable, pas un chemin de fichier sûr.[1], [2]
Confinement de chemin
Vérification qui résout le chemin candidat et prouve qu’il reste sous le dossier de stockage autorisé avant toute création ou écriture.[3], [4], [7]
Note sur les identifiants
Le GHSA associé de Langflow indique CVE-2026-33309, tandis que Tenable et Google GTIG utilisent CVE-2026-5027. Cet article suit l’identifiant de GTIG et conserve les deux références sans fusionner leurs métadonnées.[4], [5], [6]

Correspondances de référentiels

  • Référence CWE pour la faiblesse décrite dans ce guide : CWE-22

Analyse de Cause Racine

La fiche CVE-2026-5027 de Tenable décrit POST /api/v2/files acceptant un nom multipart contenant des éléments de traversal et écrivant hors du dossier prévu. La frontière de sécurité comprend la route API et le stockage local : valider des paramètres d’URL ne valide pas un nom issu de Content-Disposition, et joindre ce nom au dossier ne prouve pas le confinement. Le vecteur CVE exige des privilèges faibles (PR:L) ; n’affirmez pas que la CVE contourne l’authentification. Google GTIG inclut CVE-2026-5027 parmi les vulnérabilités exploitées dans la nature, mais son résumé public n’établit pas une exécution de code universelle. L’écriture arbitraire peut avoir des conséquences plus graves selon les chemins accessibles en écriture, les privilèges du processus et la configuration ; présentez-les comme conditionnelles, pas comme un RCE garanti. Le GHSA associé de Langflow indique CVE-2026-33309 et renvoie aussi au correctif 1.9.0. Cet article suit CVE-2026-5027, comme Tenable et GTIG, et explicite l’écart d’identifiants. La PR fusionnée valide les noms côté API et applique le confinement canonique côté stockage, avant même la création des dossiers.[1], [2], [3], [4], [5], [6]

Déroulement de l'Attaque Étape par Étape

Étape 1

Un utilisateur à privilèges faibles atteint l’API d’envoi

Le vecteur CVSS de CVE-2026-5027 exige des privilèges faibles. La route concernée est POST /api/v2/files ; la fiche n’établit pas de contournement d’authentification.[1], [2]

Étape 2

La requête fournit un nom multipart

Le nom vient de métadonnées Content-Disposition contrôlées par le client. Valider les paramètres d’URL ne nettoie pas cette entrée distincte.[1], [2], [4]

Étape 3

Le chemin franchit la frontière de stockage

Sans contrôle de confinement canonique, les éléments de traversal peuvent résoudre vers un emplacement extérieur au dossier d’envoi.[1], [2], [3], [7]

Étape 4

Un fichier est écrit hors de la racine

L’impact documenté est l’écriture arbitraire. L’exécution de code dépend des chemins accessibles, des privilèges et du déploiement ; tout envoi ne produit pas nécessairement un RCE.[1], [2], [6]

Étape 5

Corrigez les deux frontières

Langflow a fusionné la validation des noms dans l’API et le confinement canonique dans le stockage pour la branche 1.9.0. Mettez à jour et vérifiez les paquets et l’image active.[2], [3], [4]

Code Source : Vulnérable vs Sécurisé

Ces extraits réduits reprennent la forme du code, sans être un diff littéral de l’amont. Le chemin vulnérable traite le nom client comme chemin de stockage. Le modèle corrigé valide le nom puis vérifie la destination canonique par rapport à la racine canonique dans la couche de stockage ; la PR amont rejette aussi les séparateurs et caractères de contrôle et vérifie le confinement avant de créer les dossiers. Gardez ce contrôle côté stockage même si la couche HTTP valide l’entrée. L’exemple requiert une version de Python prenant en charge Path.is_relative_to et ne supprime pas à lui seul les courses entre vérification et utilisation dans un dossier accessible à un attaquant. En production, utilisez des opérations de fichiers résistantes aux courses et des permissions restrictives. La défense est le confinement du chemin, pas une simple liste noire de noms.[3], [2], [4], [7]

Extrait source: Langflow api/v2/files.py et services/storage/local.py — exemple réduit de la frontière de sécurité

IMPLÉMENTATION VULNÉRABLE
# Exemple réduit du flux de données vulnérable.
new_filename = file.filename
file_path = folder_path / new_filename
await write_upload(file, file_path)
PATCH SÉCURISÉ ET ROBUSTE
from pathlib import Path

def confined_upload_path(root: Path, client_name: str | None) -> Path:
    name = Path(client_name or "").name
    if not name or name in {".", ".."} or chr(0) in name:
        raise ValueError("invalid upload filename")

    base = root.resolve()
    target = (base / name).resolve()
    if not target.is_relative_to(base):
        raise ValueError("upload path escapes storage root")
    return target

# Appelez ceci à la frontière de stockage, juste avant la création ou l’écriture.
target = confined_upload_path(upload_root, file.filename)
await write_upload(file, target)

Liste de Contrôle de Sécurité pour l'Ingénierie

Sources