受影响版本
- = 1.0.0, <= 1.0.6
- <= 0.3.79
已修复版本
- 1.0.7
- 0.3.80
描述
LangChain的提示模板系统中存在一个模板注入漏洞,允许攻击者通过模板语法访问Python对象内部。该漏洞影响接受不可信模板字符串(而不仅仅是模板变量)的应用程序中的ChatPromptTemplate及相关提示模板类。
受影响组件
- langchain-core包
- 模板格式:
- F-string模板 (template_format="f-string") - 漏洞已修复
- Mustache模板 (template_format="mustache") - 防御性加固
- Jinja2模板 (template_format="jinja2") - 防御性加固
影响
能够控制模板字符串(而不仅仅是模板变量)的攻击者可以:
- 通过属性遍历访问Python对象属性和内部属性
- 从对象内部(例如
__class__、__globals__)提取敏感信息 - 根据传递给模板的对象,可能升级为更严重的攻击
攻击向量
1. F-string 模板注入
修复前:
from langchain_core.prompts import ChatPromptTemplate
malicious_template = ChatPromptTemplate.from_messages(
[("human", "{msg.__class__.__name__}")],
template_format="f-string")
result = malicious_template.invoke({"msg": "foo", "msg.__class__.__name__": "safe_placeholder"})
# 之前返回
# >>> result.messages[0].content
# >>> 'str'
2. Mustache 模板注入
修复前:
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import HumanMessage
msg = HumanMessage("Hello")
malicious_template = ChatPromptTemplate.from_messages(
[("human", "{{question.__class__.__name__}}")],
template_format="mustache")
result = malicious_template.invoke({"question": msg})
# 之前返回: "HumanMessage" (getattr() 暴露了内部属性)
3. Jinja2 模板注入
修复前:
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import HumanMessage
msg = HumanMessage("Hello")
malicious_template = ChatPromptTemplate.from_messages(
[("human", "{{question.parse_raw}}")],
template_format="jinja2")
result = malicious_template.invoke({"question": msg})
# 可以访问对象上的非双下划线属性/方法
根本原因
- F-string模板: 实现使用Python的string.Formatter().parse()从模板字符串中提取变量名。该方法返回完整的字段表达式,包括属性访问语法。
- Mustache模板: 设计上使用getattr()作为后备,以支持访问对象上的属性。
- Jinja2模板: Jinja2默认的SandboxedEnvironment阻止双下划线属性,但允许访问对象上的其他属性和方法。
谁受影响?
高风险场景
如果您的应用程序符合以下情况,则受影响:
- 接受来自不可信源(用户输入、外部API、数据库)的模板字符串
- 根据用户提供的模式动态构建提示模板
- 允许用户自定义或创建提示模板
低风险/无风险场景
如果符合以下情况,则不受影响:
- 模板字符串在您的应用程序代码中是硬编码的
- 模板字符串仅来自受信任、可控的来源
- 用户只能提供模板变量的值,而不能控制模板结构本身
修复方案
F-string 模板
- 添加验证以确保变量名必须是有效的Python标识符
- 拒绝诸如{obj.attr}、{obj[0]}或{obj.class}的语法
- 只允许简单的变量名:{variable_name}
Mustache 模板(防御性加固)
- 用严格的类型检查替换了
getattr()后备方案 - 只允许遍历到
dict、list和tuple类型 - 阻止对任意Python对象的属性访问
Jinja2 模板(防御性加固)
- 引入了
_RestrictedSandboxedEnvironment,阻止所有属性/方法访问 - 只允许从上下文字典中进行简单的变量查找
- 在任何属性访问尝试上引发
SecurityError
补救措施
立即行动
- 审核您的代码,查找任何模板字符串来自不可信源的位置
- 更新到已修复版本的langchain-core
- 审查模板使用情况,确保模板结构和用户数据分离
最佳实践
- 考虑是否需要模板 - 许多应用程序可以直接使用消息对象(HumanMessage、AIMessage等)而无需模板
- Jinja2仅用于受信任源 - 仅在完全控制模板内容时使用Jinja2模板
参考资料
- GHSA-6qv9-48xg-fc7f
- langchain-ai/langchain@c4b6ba2
- langchain-ai/langchain@fa7789d
- https://nvd.nist.gov/vuln/detail/CVE-2025-65106
- pypi模块地址:https://pypi.org/project/langchain-core/
- github项目地址:https://github.com/langchain-ai/langchain.git
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf
客服小蜜蜂(微信:freebee1024)



