首页 网络安全 正文
  • 本文约3874字,阅读需19分钟
  • 4
  • 0

LangChain 序列化注入漏洞CVE-2025-68664

摘要

栋科技漏洞库关注到 LangChain 中存在的序列化注入漏洞,该漏洞现在已经被追踪为CVE-2025-68664,该漏洞的CVSS 3.1评分高达9.3。

LangChain 是一个面向大语言模型(LLM)的应用开发框架,目标是简化复杂 LLM 应用的构建流程,通过标准化的组件和链式调用模型。

一、基本情况

LangChain 通过提供标准化的组件、灵活的链式调用逻辑和丰富的集成生态,从而能让开发者能够快速搭建出超越单一 LLM 能力的应用。

LangChain 序列化注入漏洞CVE-2025-68664

LangChain 最初是由Python开发的,它拥有非常丰富的生态系统,支持与几乎所有主流的 LLM 提供商、向量数据库、工具、框架的集成。

栋科技漏洞库关注到 LangChain 中存在的序列化注入漏洞,该漏洞现在已经被追踪为CVE-2025-68664,该漏洞的CVSS 3.1评分高达9.3。

二、漏洞分析

LangChain Core 是 LangChain 生态开源 Python 核心库,负责序列化与反序列化处理,用于大模型链路中消息、元数据与运行状态传递。

CVE-2025-68664是一个序列化注入漏洞,漏洞源于dumps()与dumpd()函数在处理自由字典时未正确转义包含“lc”关键字的用户可控数据。

'lc'键由LangChain内部用于标记序列化的对象。

当用户控制的数据包含此键结构时,在反序列化过程中将其视为合法的LangChain对象,而不是普通的用户数据。

这个LangChain的dumps()dumpd()函数存在序列化注入漏洞,这些函数在序列化自由格式字典时不会转义具有'lc'键的字典。

导致其在load()loads()反序列化过程中被误识别为合法的LangChain对象结构。

攻击者可通过在LLM响应、metadata、additional_kwargs等可控字段中注入特制序列化结构,

实现敏感环境变量泄露,或在受信命名空间内实例化具有副作用的类。

langchain_core.load.dump的dumps()/dumpd() 在序列化(如 metadata、additional_kwargs、response_metadata)时,

未对包含 'lc' 键的用户字典做转义;

'lc' 是 LangChain 内部用于标记序列化对象的字段,

导致攻击者可把形如 {"lc":1,"type":"secret","id":[...]}或构造器结构注入到用户可控数据中,

使其在后续 load()/loads() 反序列化阶段被当作合法 LangChain 对象处理,从而触发环境变量 secret 读取。

修复版本中通过在序列化阶段对含 lc 键的普通字典进行转义封装,并在反序列化时严格区分用户数据与内部对象结构,

同时收紧默认反序列化策略,阻断注入结构被解析执行的路径。

1、攻击面

核心漏洞存在于dumps()dumpd():这些函数未能对包含'lc'键的用户控制字典进行转义。

当这些未转义的数据随后通过load()loads()反序列化时,注入的结构被当作合法的LangChain对象,并非普通的用户数据。

这个逃逸漏洞启用了许多攻击向量:

通过用户数据注入:恶意LangChain对象结构可以通过用户控制的字段注入,如metadata、additional_kwargs 或 response_metadata

在受信任的命名空间内进行类实例化:

注入清单可以实例化任何Serializable子类,但仅限于预先批准的受信任命名空间(langchain_core,langchain,langchain_community)。

这包括在__init__中具有副作用的类(网络调用、文件操作等)。

请注意,命名空间验证在该补丁之前已经实施,因此这些受信任命名空间之外的任意类无法被实例化。

2、安全强化

此补丁修复了 dumps()dumpd() 中的转义错误,并在 load()loads() 中引入了新的限制性默认设置:

通过 allowed_objects="core" 进行允许列表强制执行(限制在 序列化映射 ),secrets_from_envTrue 更改为 False

以及通过 init_validator 默认阻止 Jinja2 模板。这些对某些用例是破坏性变化。

3、受影响的人是谁?

如果应用程序具有以下特征,则存在漏洞:

使用 astream_events(version="v1") — v1 版本的实现内部使用了易受攻击的序列化。

注意:astream_events(version="v2") 不受影响。

使用Runnable.astream_log() — 此方法内部对流输出使用易受攻击的序列化。

调用 dumps()dumpd() 不信任的数据,然后使用 load()loads()反序列化

 —— 若用户控制数据(如来自 LLM 响应、元数据字段或用户输入的数据)含 'lc' 关键结构,信任自己序列化输出会让你 vulnerable。

反序列化不可信数据与load()loads() — 直接反序列化可能包含注入的'lc'结构的不可信数据。

使用RunnableWithMessageHistory — 消息历史处理中的内部序列化。

使用InMemoryVectorStore.load()来反序列化不可信的文档。

从缓存中加载不受信任的生成内容使用langchain-community缓存.

LangChain Hub 加载不可信的清单通过 hub.pull.

在不可信的运行中使用StringRunEvaluatorChain

使用 create_lc_storecreate_kv_docstore 与不可信的文档一起使用。

使用MultiVectorRetriever与包含不受信任文档的字节存储设备一起使用。

使用LangSmithRunChatLoader处理包含不可信消息的运行。

最常的攻击向量是通过LLM响应字段,如additional_kwargsresponse_metadata

这些字段可以通过提示注入控制,然后在流操作中序列化/反序列化。

4、影响

攻击者控制序列化数据时,可以通过注入{"lc": 1, "type": "secret", "id": ["ENV_VAR"]}

来在反序列化期间(当secrets_from_env=True,这是旧的默认值)加载环境变量,从而提取环境变量秘密。

他们还可以通过注入构造函数结构来实例化受控参数的类,以实例化受信任命名空间内的任何类,并使用攻击者控制的参数,

这可能会触发诸如网络调用或文件操作等副作用。

5、关键严重性因素

影响序列化路径 - 信任自身序列化输出的应用程序易受攻击

secrets_from_env=True(旧默认值)结合时启用秘密提取

LLM 响应在 additional_kwargs 可以通过提示注入进行控制

三、POC概念验证

1、利用示例

管理员已设置登录后刷新可查看

2、安全强化变更(重大变更)

此补丁对 load() loads() 作出了三个重大更改:

allowed_objects参数(默认为'core'):强制允许反序列化的类白名单。

该'all'选项对应于在中指定的对象列表mappings.py,而'core'选项限制在langchain_core中的对象。

我们建议用户明确指定他们希望允许序列化/反序列化的对象。

secrets_from_env 默认值从 True 更改为 False:禁用从环境自动加载秘密

init_validator参数(默认为default_init_validator):默认阻止 Jinja2 模板

3、迁移指南

1.大多数用户无需更改

如果你正在反序列化标准的LangChain类型,

(消息、文档、提示、可信合作伙伴集成,例如 ChatOpenAI、ChatAnthropic 等等),你的代码将无需更改即可工作:

from langchain_core.load import load

# Uses default allowlist from serialization mappings
obj = load(serialized_data)

2.自定义类

如果你正在反序列化不在序列化映射中的自定义类,请将它们添加到允许列表中:

from langchain_core.load import load
from my_package import MyCustomClass

# Specify the classes you need
obj = load(serialized_data, allowed_objects=[MyCustomClass])

3.对于 Jinja2 模板

Jinja2 模板现在默认被阻止,因为它们可以执行任意代码。如果你需要 Jinja2 模板,请传递 init_validator=None:

from langchain_core.load import load
from langchain_core.prompts import PromptTemplate

obj = load(
    serialized_data,
    allowed_objects=[PromptTemplate],
    init_validator=None
)

警告

仅在您信任序列化数据时禁用 init_validator Jinja2 模板可以执行任意 Python 代码。

4、来自环境的秘密

secrets_from_env 现默认为 False。如果您需要从环境变量加载秘密:

from langchain_core.load import load

obj = load(serialized_data, secrets_from_env=True)

四、影响范围

1.0.0 <= langchain < 1.2.5

langchain < 0.3.81

五、修复建议

langchain >= 1.2.5

langchain >= 0.3.81

六、参考链接

管理员已设置登录后刷新可查看



扫描二维码,在手机上阅读
评论
更换验证码
友情链接