flawopen.com/AI Security/langgraph-js-custom-auth-cross-user-store-access
LangGraph JS Auth:跨用户 Store 数据访问
langgraph-api 0.15.0之前可能丢失JS/TS自定义认证对Store命名空间的重写,导致跨用户访问。请升级至0.15.0。[1], [2]
想象图书管理员检查了你的借书证,然后让另一个柜台取书。第二个柜台把你的书架编号写进请求,但交接时修改丢失,最终按访客最初提供的书架编号取书。受影响的 JavaScript/TypeScript 认证路径可能在授权运行时与 Store 操作之间丢失 namespace 重写。修复会传递授权后的 namespace,并在使用 Store 前进行验证。[1]
核心概念与专有名词
GHSA-4hm6-w6qq-w73v- LangGraph 于 2026 年 9 月 28 日发布的高危安全公告。未分配 CVE。受影响软件包为 langgraph-api,0.15.0 已修复。[1]
Store namespace- 用于对 LangGraph Store 记录分组的层级名称。应用通常将用户或租户标识放入其中以隔离数据。[1]
自定义授权处理器- 应用代码,用于判断已认证请求是否可访问资源,并可在 Store 操作前重写 namespace。[1]
框架映射
攻击执行流程分解
确认部署是否符合条件
检查 langgraph-api 是否 >=0.1.2 且 <0.15.0,以及服务端是否使用 JavaScript 或 TypeScript 自定义认证处理器。[1]
定位 namespace 重写逻辑
处理器会修改请求的 namespace,以加入或强制执行已认证用户的身份,而不是拒绝超出其 namespace 的请求。[1]
授权结果跨越运行时边界
受影响版本可能无法将 namespace 修改传递给 Store 操作,导致继续使用请求方最初提供的 namespace。[1]
已认证用户访问其他 namespace
普通账号可以针对自身 namespace 之外的 Store 记录请求操作。公告列出的影响包括读取、覆盖、搜索和删除。[1]
根本原因剖析 (Root Cause)
LangGraph 维护者于 2026 年 9 月 28 日发布的 GHSA 描述了 langgraph-api >=0.1.2 且 <0.15.0 中的问题,且必须同时满足以下条件:部署使用 JavaScript 或 TypeScript 自定义认证;Store 授权处理器通过重写请求的 namespace 将数据限制到当前用户;普通已认证用户可以发起 Store 操作;多个用户的数据经过该授权路径。公告指出 Python 自定义认证处理器不受影响;若 JavaScript/TypeScript 处理器选择拒绝未授权 namespace,而不是重写它们,也不受影响。处理器对 namespace 的修改可能在运行时边界丢失,因此 Store 操作使用了原始请求中的 namespace。已认证用户可能读取、覆盖、搜索或删除授权 namespace 之外的记录。这不绕过登录,也不是未认证远程攻击。公告评级为高危,CVSS 4.0 为 8.6,并列出 CWE-639 和 CWE-863。0.15.0 会跨边界传递处理器修改,验证最终 namespace,并拒绝格式错误或未能安全应用的授权更改。若暂时不能升级,维护者建议所有 Store 操作都拒绝未授权 namespace。代码对比是数据流的简化 TypeScript 示意,并非 SDK 源码。[1]
源代码对比:漏洞与安全实现
此精简 TypeScript 示例用于说明边界契约;函数名称和结果格式仅为示意,并非 LangGraph SDK 源码。公告确认 JS/TS 授权修改可能在 Store 操作前丢失,但未公开这一确切的内部实现。因此,易受影响的一侧只表示公告中的不变量:Store 使用请求中的 namespace,而不是授权后的 namespace。修复一侧使用并验证授权结果。维护者记录的临时方案是对每项 Store 操作拒绝未授权 namespace,而不是重写它。[1]
源码摘录: LangGraph API 授权到 Store 的边界——精简示意契约
type StoreRequest = { namespace: string[]; key: string };
type AuthorizationResult = { allowed: boolean; namespace: string[] };
async function readStore(userId: string, request: StoreRequest) {
const authorization = await authorizeStore(userId, request); // Illustrative bridge contract.
return store.get(request.namespace, request.key); // The bridge drops the authorized result.
}
type StoreRequest = { namespace: string[]; key: string };
type AuthorizationResult = { allowed: boolean; namespace: string[] };
async function readStore(userId: string, request: StoreRequest) {
const authorization = await authorizeStore(userId, request); // Illustrative bridge contract.
if (!authorization.allowed) throw new Error("forbidden");
const namespace = validateAuthorizedNamespace(userId, authorization.namespace);
return store.get(namespace, request.key); // Apply the authorized result.
}
工程与系统安全加固清单
- ✓盘点
langgraph-api版本并识别使用 JavaScript/TypeScript 自定义认证的部署;Python 处理器不在此公告的影响范围内。[1] - ✓将受影响部署升级到
langgraph-api>=0.15.0,并验证实际部署的构件,而不只检查锁文件或源代码分支。[1], [2] - ✓升级前,让每个 Store 授权处理器拒绝超出已认证用户 namespace 的请求;不要依赖可能丢失的重写结果。[1]
- ✓使用两个测试身份测试
get、put、search、delete和 namespace 列举操作;确认每项操作都绑定授权 namespace,并拒绝跨用户访问。[1] - ✓检查可用的 Store 访问和变更日志,查找对其他用户 namespace 的读取、搜索或写入。如发现未授权变更,先保全证据并评估受影响记录,再进行清理。[1], [5]