flawopen.com/AI Security/langgraph-js-graph-input-control-directive-october-2026
GHSA-wp87-994x-j95x: JSON confundido con una orden del grafo
LangGraph.js <1.4.21 podía tratar JSON corriente como una orden de control y saltarse validaciones o aprobaciones. Actualiza y valida el estado en el servidor.[1]
Imagina que el grafo es una estación: el equipaje debe pasar inspección antes de subir. En las versiones afectadas, una etiqueta que solo decía “Command” podía confundirse con una orden autorizada para cambiar de vía. La corrección distingue los objetos sencillos de los objetos Command, pero la aplicación aún debe comprobar permisos antes de cada acción sensible.[1], [2]
Conceptos Clave y Términos
GHSA-wp87-994x-j95x- Aviso High de LangChain publicado el 8 de octubre de 2026; indica CVSS 4.0 7,6,
CWE-20y ningún CVE conocido.[1] Entrada del grafo- Objeto de estado entregado a una ejecución de LangGraph.js; el servidor debe validarlo y seleccionar sus campos.[1]
Command- Objeto de LangGraph.js que actualiza el estado o dirige la ejecución; el JSON normal debe seguir siendo dato.[2]
Límite de control- Frontera donde los datos se interpretan como instrucciones para elegir nodos o cambiar el estado.[1]
Mapeos de marcos
- Referencia CWE para la debilidad descrita en esta guía: CWE-20
Flujo de Ataque Paso a Paso
La aplicación recibe JSON del llamador
El despliegue afectado entrega JSON no confiable directamente al grafo en vez de construir estado validado en el servidor.[1]
Puede omitirse el procesamiento normal
El objeto puede interpretarse como una actualización de estado o una instrucción de ruta y evitar nodos de validación o aprobación de la aplicación.[1]
Los permisos de herramientas amplían el impacto
Si el grafo ofrece herramientas sensibles, el aviso indica que una entrada del atacante podría ejecutarlas con permisos de la aplicación. Vuelve a autorizar en cada operación.[1]
Análisis de Causa Raíz
El aviso afecta a @langchain/langgraph >=0.2.23 y <1.4.21. La aplicación debe pasar JSON no confiable directamente al grafo y confiar en que el recorrido normal aplique validación o autorización. La PR explica que isCommand reconocía un valor solo por el campo lg_name; por eso un objeto JSON normal podía tratarse como Command. El grafo podía aplicar update o goto antes de los nodos de validación o aprobación de la aplicación. El aviso describe el posible uso no autorizado de herramientas sensibles con permisos de la aplicación. La versión 1.4.21 rechaza objetos simples como Command y conserva instancias reales, incluso las creadas por otra copia instalada del paquete. Esto no sustituye la creación del estado en el servidor, la lista permitida de campos ni la autorización en cada operación sensible. La clasificación es CWE-20, High, CVSS 4.0 7,6; no se conoce un CVE.[1], [2]
Código Fuente: Vulnerable vs. Seguro
Este ejemplo reducido en TypeScript refleja el cambio de la PR #2966: lg_name por sí solo ya no convierte un objeto simple en Command. No es código literal ni una implementación completa. Tras la corrección, el JSON analizado sigue el recorrido de estado normal y los objetos Command auténticos conservan el control del grafo. No uses la forma del objeto como autorización. Construye el estado en el servidor con una lista permitida y autoriza cada operación sensible.[2]
Fragmento de origen: Ilustración conductual reducida del discriminador Command de LangGraph.js; no es el código fuente completo
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";
}
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";
}
Lista de Verificación de Seguridad para Ingeniería
- ✓Actualiza @langchain/langgraph a 1.4.21 o posterior; comprueba la versión en el archivo de bloqueo y en el artefacto desplegado.[1], [2]
- ✓No pases JSON de la petición directamente a
graph.invoke()ograph.stream(); crea el estado en el servidor con una lista explícita de campos aceptados.[1] - ✓Separa los objetos de control del estado del llamador y prueba que JSON analizado sea entrada normal aunque incluya campos de nombre parecido.[2]
- ✓Autoriza cada herramienta o efecto sensible en el punto de operación con la identidad autenticada y el ámbito del recurso; no dependas solo de un nodo anterior.[1]
- ✓Añade una prueba de integración que envíe JSON no confiable por el grafo y compruebe que una herramienta sensible simulada nunca se invoque sin autorización del principal autenticado para el recurso objetivo.[1], [2]