flawopen.com/AI Security/langgraph-js-graph-input-control-directive-october-2026
GHSA-wp87-994x-j95x: JSON confundido com comando do grafo
LangGraph.js <1.4.21 podia tratar JSON comum como diretiva de controle e ignorar etapas de validação ou aprovação. Atualize e valide o estado no servidor.[1]
Pense no grafo como uma estação: a bagagem deve passar pela inspeção antes de embarcar. Nas versões afetadas, uma etiqueta escrita “Command” podia ser confundida com uma ordem autorizada para mudar os trilhos. A correção separa objetos simples de objetos Command, mas a aplicação ainda precisa conferir a permissão antes de cada ação sensível.[1], [2]
Conceitos Centrais e Termos
GHSA-wp87-994x-j95x- Aviso High do LangChain, publicado em 8 de outubro de 2026; indica CVSS 4.0 7,6,
CWE-20e nenhum CVE conhecido.[1] Entrada do grafo- Objeto de estado entregue a uma execução LangGraph.js; o servidor deve validá-lo e selecionar seus campos.[1]
Command- Objeto LangGraph.js que atualiza estado ou direciona execução; JSON comum deve continuar sendo dado.[2]
Fronteira de controle- Fronteira onde dados passam a ser interpretados como instruções que escolhem nós ou alteram estado.[1]
Mapeamentos de frameworks
- Referência CWE para a fraqueza descrita neste guia: CWE-20
Fluxo de Ataque Passo a Paso
A aplicação recebe JSON do chamador
A implantação afetada entrega JSON não confiável diretamente ao grafo, sem criar estado validado no servidor.[1]
O processamento normal pode ser ignorado
O objeto pode ser tratado como atualização de estado ou instrução de roteamento, contornando nós de validação ou aprovação definidos pela aplicação.[1]
Permissões das ferramentas ampliam o impacto
Se o grafo expõe ferramentas sensíveis, o aviso diz que entradas de um invasor podem acioná-las com as permissões da aplicação. Reautorize na fronteira da operação.[1]
Análise de Causa Raiz
O aviso cobre @langchain/langgraph >=0.2.23 e <1.4.21. A aplicação precisa passar JSON não confiável diretamente ao grafo e confiar que o fluxo normal fará validação ou autorização. A PR de correção explica que isCommand antes reconhecia um valor apenas pelo campo lg_name; assim, um objeto JSON comum podia ser tratado como Command. O grafo poderia aplicar update ou goto antes dos nós de validação/aprovação definidos pela aplicação. O aviso descreve possível execução não autorizada de ferramentas sensíveis com as permissões da aplicação. A versão 1.4.21 rejeita objetos simples como Command e preserva instâncias reais, inclusive de outra cópia instalada do pacote. Isso não substitui a criação de estado no servidor, a lista de campos permitidos nem a autorização em cada operação sensível. A classificação é CWE-20, High, CVSS 4.0 7,6; não há CVE conhecido.[1], [2]
Código-Fonte: Vulnerável vs. Seguro
Esta ilustração TypeScript reduzida representa a alteração descrita na PR #2966: o campo lg_name sozinho deixa de transformar um objeto simples em Command. Não é código literal nem uma implementação completa. JSON analisado segue o caminho de estado comum após a correção; objetos Command reais continuam controlando o grafo. Não use o formato do objeto como autorização. Monte o estado no servidor a partir de campos permitidos e autorize cada operação sensível.[2]
Trecho de origem: Ilustração comportamental reduzida do discriminador Command do LangGraph.js; não é o código-fonte 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 Verificação de Segurança para Engenharia
- ✓Atualize @langchain/langgraph para 1.4.21 ou posterior e confirme a versão no lockfile e no artefato implantado.[1], [2]
- ✓Não passe JSON da requisição diretamente a
graph.invoke()ougraph.stream(); monte o estado no servidor usando uma lista explícita de campos aceitos.[1] - ✓Mantenha objetos de controle separados do estado controlado pelo chamador; teste que JSON analisado seja entrada comum mesmo com campos de nome semelhante.[2]
- ✓Autorize cada ferramenta ou efeito sensível no ponto de operação, usando identidade autenticada e escopo do recurso; não dependa apenas de um nó anterior.[1]
- ✓Adicione um teste de integração que envie JSON não confiável pelo grafo e confirme que o stub de uma ferramenta sensível nunca é chamado sem autorização do principal autenticado para o recurso alvo.[1], [2]