LangChain序列化注入漏洞致密秘钥泄露技术分析
漏洞详情
包信息
-
npm: @langchain/core (npm)
-
受影响版本: >=1.0.0, <1.1.8 或 <0.3.80
-
已修复版本: 1.1.8, 0.3.80
-
npm: langchain (npm)
-
受影响版本: >=1.0.0, <1.2.3 或 <0.3.37
-
已修复版本: 1.2.3, 0.3.37
技术描述
漏洞背景
LangChain JS的toJSON()方法(以及随后使用JSON.stringify()字符串化对象时)存在序列化注入漏洞。该方法在序列化kwargs中的自由格式数据时,未对包含’lc’键的对象进行转义。’lc’键被LangChain内部用来标记序列化对象。当用户控制的数据包含此键结构时,在反序列化过程中会被视为合法的LangChain对象而非普通用户数据。
攻击面
核心漏洞位于Serializable.toJSON()方法:该方法未能转义kwargs(例如additional_kwargs、metadata、response_metadata)中包含’lc’键的用户控制对象。当这些未转义的数据后来通过load()反序列化时,注入的结构会被视为合法的LangChain对象而非普通用户数据。
此转义漏洞启用了多种攻击向量:
- 通过用户数据注入:恶意LangChain对象结构可以通过用户控制的字段如
metadata、additional_kwargs或response_metadata注入 - 秘密提取:当启用
secretsFromEnv时(该选项没有明确的默认值,实际上默认行为为true),注入的秘密结构可以提取环境变量 - 通过导入映射进行类实例化:注入的构造器结构可以使用攻击者控制的参数实例化提供的导入映射中的任何类
关于导入映射的说明:类必须明确包含在导入映射中才能被实例化。核心导入映射包括标准类型(消息、提示、文档),用户可以通过importMap和optionalImportsMap选项扩展此映射。这种架构自然地限制了攻击面——因为用户通过他们提供的导入映射控制哪些类可用,所以不需要allowedObjects参数。
受影响的应用程序
如果应用程序满足以下条件,则易受攻击:
- 通过
JSON.stringify()在Serializable对象上序列化不可信数据,然后使用load()反序列化——如果用户控制的数据(例如来自LLM响应、元数据字段或用户输入)包含’lc’键结构,那么信任自己的序列化输出会使您易受攻击。 - 使用
load()直接反序列化不可信数据——直接反序列化可能包含注入’lc’结构的不可信数据。 - 使用LangGraph检查点——检查点序列化/反序列化路径可能受影响。
最常见的攻击向量是通过LLM响应字段,如additional_kwargs或response_metadata,这些字段可以通过提示注入控制,然后在流操作中序列化/反序列化。
漏洞影响
控制序列化数据的攻击者可以通过注入{"lc": 1, "type": "secret", "id": ["ENV_VAR"]}来提取环境变量秘密(当secretsFromEnv: true时)。他们还可以通过注入构造器结构来使用受控参数实例化任何类,可能触发网络调用或文件操作等副作用。
关键严重性因素:
- 影响序列化路径——信任自己序列化输出的应用程序易受攻击
- 当与
secretsFromEnv: true结合时,可实现秘密提取 additional_kwargs中的LLM响应可以通过提示注入控制
漏洞利用示例
|
|
安全加固变更
此补丁为load()引入了以下变更:
-
secretsFromEnv默认值改为false:禁用从环境变量自动加载秘密。未在secretsMap中找到的秘密现在会抛出错误,而不是从process.env加载。这种故障安全行为确保立即捕获缺失的秘密,而不是静默地继续使用null值。 -
新的
maxDepth参数(默认为50):防止通过可能导致堆栈溢出的深度嵌套JSON结构进行拒绝服务攻击。 -
toJSON()中的转义机制:现在在序列化期间将包含’lc’键的用户控制对象包装在{"__lc_escaped__": {...}}中,并在反序列化期间作为纯数据解包。 -
JSDoc安全警告:所有导入映射选项(
importMap、optionalImportsMap、optionalImportEntrypoints)现在都包含安全警告,提示切勿从用户输入填充它们。
迁移指南
大多数用户无需更改
如果您使用核心导入映射反序列化标准LangChain类型(消息、文档、提示),您的代码将无需更改即可工作:
|
|
从环境变量加载秘密
secretsFromEnv现在默认为false,缺失的秘密会抛出错误。如果您需要加载秘密:
|
|
警告:仅当信任序列化数据时才启用secretsFromEnv。不可信数据可能提取任何环境变量。
注意:如果遇到秘密引用但未在secretsMap中找到(且secretsFromEnv为false或环境中没有该秘密),则会抛出错误。这种故障安全行为确保您知道缺失的秘密,而不是静默地接收null值。
深度嵌套结构
如果您有超过默认深度限制50的合法深度嵌套数据:
|
|
自定义导入映射
如果您提供自定义导入映射,请确保它们仅包含可信模块:
|
|
安全评分
- 严重等级: 高
- CVSS总体评分: 8.6/10
- CVSS v3基础指标: AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
- EPSS评分: 0.061%(第19百分位)
弱点分类
- CWE-ID: CWE-502
- 弱点描述: 不可信数据的反序列化 - 产品在反序列化不可信数据时,未能充分确保生成的数据有效。
参考链接
- GHSA-r399-636x-v7f6
- langchain-ai/langchainjs@e5063f9
- https://github.com/langchain-ai/langchainjs/releases/tag/%40langchain%2Fcore%401.1.8
- https://github.com/langchain-ai/langchainjs/releases/tag/langchain%401.2.3
- https://nvd.nist.gov/vuln/detail/CVE-2025-68665
致谢
- ccurme(修复开发者)
- mdrxy(修复开发者)
- 0xn3va(报告者)
- yardenporat353(报告者)
- VladimirEliTokarev(报告者)
- hntrl(修复开发者)
- siewer(报告者)
- jacoblee93(修复验证者)