FlawOpen

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

● CWE-20 · CVSS v4 7.6[1] · Alta
Investigación · FlawOpen

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]

Vector 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]
💡 Explicación en Lenguaje Sencillo (ELI5)

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-20 y 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

Paso 1

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]

Paso 2

Los datos se confunden con control

Antes de 1.4.21, el marcador lg_name por sí solo podía hacer que un objeto simple pareciera un Command. El fallo está en el reconocimiento del tipo, no en el análisis de JSON.[1], [2]

Paso 3

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]

Paso 4

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

IMPLEMENTACIÓN VULNERABLE
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";
}
PARCHE SEGURO Y ROBUSTO
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

Fuentes

← AI Security Directory →