flawopen.com/AI Security/langgraph-js-graph-input-control-directive-october-2026
GHSA-wp87-994x-j95x:普通 JSON 被误判为图控制命令
LangGraph.js <1.4.21 可能把普通 JSON 当成控制指令,绕过应用的验证或审批节点。请升级,并在服务器端验证状态。[1]
把图工作流想成火车站:行李必须先检查再上车。受影响版本可能把只写着“Command”的标签误认成有权限的道岔指令。修复后普通对象与 Command 对象会被区分,但应用仍须在每次敏感操作前检查权限。[1], [2]
核心概念与专有名词
GHSA-wp87-994x-j95x- LangChain 于 2026 年 10 月 8 日发布的 High 级安全公告;给出 CVSS 4.0 7.6、
CWE-20,且没有已知 CVE。[1] 图输入- 传入 LangGraph.js 执行的状态对象;服务器应验证状态并只选取允许字段。[1]
Command- 可更新状态或引导执行的 LangGraph.js 对象;普通 JSON 必须仍被视为数据。[2]
控制边界- 应用数据被解释为选择节点或改变状态指令的位置。[1]
框架映射
- 本指南所述弱点的 CWE 参考: CWE-20
攻击执行流程分解
应用接收调用方提供的 JSON
受影响部署把不可信 JSON 直接交给图,而不是在服务器端构造已验证的状态。[1]
常规处理流程可能被跳过
该对象可能被当作状态更新或路由指令,从而绕过应用定义的验证或审批节点。[1]
工具权限会放大影响
如果图暴露敏感工具,攻击者输入可能借助应用权限执行工具。应在操作边界再次授权。[1]
根本原因剖析 (Root Cause)
公告涉及 @langchain/langgraph >=0.2.23 且 <1.4.21。只有应用把不可信 JSON 直接传入图,并依赖常规执行路径验证或授权时,部署才符合受影响条件。上游 PR 说明,旧版 isCommand 仅凭 lg_name 字段识别对象,因此普通 JSON 对象也可能被误认为 Command。图随后可能在应用定义的验证或审批节点之前应用 update 或 goto。若图提供敏感工具,公告指出攻击者可能借应用权限执行未授权工具。1.4.21 会拒绝把普通对象视为 Command,同时保留真正的实例。这不能取代服务器端构造状态、字段白名单或每个敏感操作的授权。公告标记 CWE-20、High、CVSS 4.0 7.6,且没有已知 CVE。[1], [2]
源代码对比:漏洞与安全实现
这个精简 TypeScript 示例体现 PR #2966 描述的改动:仅有 lg_name 不再足以把普通对象认作 Command。它不是逐字源码,也不是完整图实现。修复后,解析得到的 JSON 走普通状态路径,真正的 Command 对象仍可控制图。对象外形不能代替授权。请在服务器端通过字段白名单构造状态,并对每项敏感操作单独授权。[2]
源码摘录: LangGraph.js Command 判别器的简化行为示例;并非完整源码
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";
}
工程与系统安全加固清单
- ✓将 @langchain/langgraph 升级到 1.4.21 或更高版本,并核对锁文件和部署制品中的实际版本。[1], [2]
- ✓不要把请求 JSON 直接传给
graph.invoke()或graph.stream();在服务器端按明确的允许字段集合构造图状态。[1] - ✓将控制对象与调用方可控状态分开,并测试带有类似字段名的 JSON 仍作为普通输入处理。[2]
- ✓在每个敏感工具或副作用的操作边界,依据已认证主体和资源范围检查权限,不要只依赖前序节点。[1]
- ✓添加集成测试,将不可信 JSON 送入图,并断言:若已认证主体未获准访问目标资源,敏感工具的测试替身绝不会被调用。[1], [2]