FlawOpen

flawopen.com/AI Security/langgraph-js-graph-input-control-directive-october-2026

● CWE-20 · CVSS v4 7.6[1] · Haute
Recherche · FlawOpen

GHSA-wp87-994x-j95x : JSON pris pour un ordre du graphe

LangGraph.js <1.4.21 pouvait interpréter un JSON ordinaire comme une directive de contrôle et contourner validation ou approbation. Mettez à jour et validez l’état côté serveur.[1]

Vecteur CVSSCVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N[1]
💡 Explication en Langage Simple (ELI5)

Imaginez un graphe comme une gare : les bagages doivent être contrôlés avant l’embarquement. Dans les versions concernées, une étiquette « Command » pouvait passer pour un ordre autorisé de changer de voie. Le correctif distingue les objets simples des objets Command, mais l’application doit toujours vérifier les droits avant chaque action sensible.[1], [2]

Concepts Clés et Termes

GHSA-wp87-994x-j95x
Avis High de LangChain publié le 8 octobre 2026 ; il indique CVSS 4.0 7,6, CWE-20 et aucun CVE connu.[1]
Entrée du graphe
Objet d’état fourni à une exécution LangGraph.js ; le serveur doit le valider et sélectionner ses champs.[1]
Command
Objet LangGraph.js qui met à jour l’état ou dirige l’exécution ; le JSON ordinaire reste une donnée.[2]
Frontière de contrôle
Frontière où les données deviennent des instructions choisissant des nœuds ou modifiant l’état.[1]

Correspondances de référentiels

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

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

Étape 1

L’application reçoit le JSON du client

Le déploiement concerné transmet directement au graphe un JSON non fiable au lieu de construire un état validé côté serveur.[1]

Étape 2

Une donnée est prise pour du contrôle

Avant 1.4.21, le marqueur lg_name seul pouvait faire passer un objet simple pour un Command. Le défaut porte sur la reconnaissance du type, pas sur l’analyse JSON.[1], [2]

Étape 3

Le traitement normal peut être contourné

L’objet peut devenir une mise à jour d’état ou une instruction de routage et éviter les nœuds de validation ou d’approbation de l’application.[1]

Étape 4

Les droits des outils amplifient l’impact

Si le graphe expose des outils sensibles, une entrée malveillante peut, selon l’avis, les exécuter avec les droits de l’application. Réautorisez au niveau de chaque opération.[1]

Analyse de Cause Racine

L’avis concerne @langchain/langgraph >=0.2.23 et <1.4.21. L’application doit transmettre directement au graphe un JSON non fiable et compter sur son chemin normal pour valider ou autoriser. La PR indique que isCommand reconnaissait auparavant une valeur à partir du seul champ lg_name ; un objet JSON ordinaire pouvait donc être pris pour un Command. Le graphe pouvait appliquer update ou goto avant les nœuds de validation ou d’approbation de l’application. L’avis décrit un risque d’exécution non autorisée d’outils sensibles avec les droits de l’application. La version 1.4.21 rejette les objets simples comme Command tout en conservant les vraies instances, y compris celles d’une autre copie installée. Cela ne remplace ni la construction de l’état côté serveur, ni la liste des champs admis, ni l’autorisation à chaque opération sensible. L’avis attribue CWE-20, High et CVSS 4.0 7,6 ; aucun CVE n’est connu.[1], [2]

Code Source : Vulnérable vs Sécurisé

Cet exemple TypeScript réduit reprend le changement décrit dans la PR #2966 : lg_name seul ne suffit plus à faire d’un objet simple un Command. Ce n’est ni le code source exact ni un graphe complet. Après correction, le JSON analysé suit le chemin d’état ordinaire et les vrais objets Command gardent leur fonction de contrôle. La forme d’un objet ne constitue pas une autorisation. Construisez l’état côté serveur à partir d’une liste de champs admis et autorisez chaque opération sensible.[2]

Extrait source: Illustration comportementale réduite du discriminateur Command de LangGraph.js ; pas le code source complet

IMPLÉMENTATION VULNÉRABLE
type CommandLike = { lg_name: string; goto?: unknown; update?: unknown };

function isCommand(value: unknown): value is CommandLike {
  return typeof value === "object" && value !== null &&
    "lg_name" in value && value.lg_name === "Command";
}
PATCH SÉCURISÉ ET ROBUSTE
type CommandLike = { lg_name: string; goto?: unknown; update?: unknown };

function isPlainObject(value: object): boolean {
  const prototype = Object.getPrototypeOf(value);
  return prototype === Object.prototype || prototype === null;
}

function isCommand(value: unknown): value is CommandLike {
  return typeof value === "object" && value !== null &&
    !isPlainObject(value) &&
    "lg_name" in value && value.lg_name === "Command";
}

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

Sources

← AI Security Directory →